From 6a2f518dfa7cb127569d21c80e91cd02907a2171 Mon Sep 17 00:00:00 2001 From: vb6174 Date: Wed, 7 Jul 2021 12:15:10 +0000 Subject: [PATCH 01/32] audio driver model codes Signed-off-by: vb6174 --- model/audio/core/include/audio_control.h | 77 ++ model/audio/core/include/audio_core.h | 96 ++ model/audio/core/include/audio_host.h | 171 +++ model/audio/core/include/audio_parse.h | 28 + model/audio/core/include/codec_core.h | 35 + model/audio/core/src/audio_core.c | 1038 ++++++++++++++ model/audio/core/src/audio_host.c | 443 ++++++ model/audio/core/src/audio_parse.c | 60 + model/audio/core/src/codec_core.c | 166 +++ .../test/unittest/common/audio_common_test.h | 49 + .../test/unittest/common/audio_core_test.cpp | 153 ++ .../test/unittest/common/audio_host_test.cpp | 51 + .../test/unittest/common/audio_parse_test.cpp | 45 + .../accessory/include/accessory_adapter.h | 71 + model/audio/device/accessory/src/accessory.c | 99 ++ .../device/codec/include/codec_adapter.h | 93 ++ model/audio/device/codec/src/codec.c | 643 +++++++++ model/audio/device/soc/include/dai_adapter.h | 53 + model/audio/device/soc/include/dsp_adapter.h | 55 + .../device/soc/include/platform_adapter.h | 136 ++ model/audio/device/soc/src/dai.c | 335 +++++ model/audio/device/soc/src/dsp.c | 483 +++++++ model/audio/device/soc/src/platform.c | 1170 ++++++++++++++++ .../dispatch/include/audio_control_dispatch.h | 54 + .../dispatch/include/audio_stream_dispatch.h | 74 + .../dispatch/src/audio_control_dispatch.c | 333 +++++ .../dispatch/src/audio_stream_dispatch.c | 1068 ++++++++++++++ .../common/audio_stream_dispatch_test.cpp | 51 + model/audio/sapm/include/audio_sapm.h | 216 +++ model/audio/sapm/src/audio_sapm.c | 1230 +++++++++++++++++ .../test/unittest/common/audio_sapm_test.cpp | 69 + test/unittest/common/hdf_main_test.c | 8 +- test/unittest/common/hdf_main_test.h | 1 + .../model/audio/include/audio_core_test.h | 46 + .../model/audio/include/audio_host_test.h | 30 + .../model/audio/include/audio_parse_test.h | 28 + .../model/audio/include/audio_sapm_test.h | 32 + .../include/audio_stream_dispatch_test.h | 29 + .../model/audio/include/hdf_audio_test.h | 61 + .../model/audio/src/audio_core_test.c | 327 +++++ .../model/audio/src/audio_host_test.c | 64 + .../model/audio/src/audio_parse_test.c | 29 + .../model/audio/src/audio_sapm_test.c | 92 ++ .../audio/src/audio_stream_dispatch_test.c | 40 + .../unittest/model/audio/src/hdf_audio_test.c | 71 + 45 files changed, 9502 insertions(+), 1 deletion(-) create mode 100755 model/audio/core/include/audio_control.h create mode 100755 model/audio/core/include/audio_core.h create mode 100755 model/audio/core/include/audio_host.h create mode 100755 model/audio/core/include/audio_parse.h create mode 100755 model/audio/core/include/codec_core.h create mode 100755 model/audio/core/src/audio_core.c create mode 100755 model/audio/core/src/audio_host.c create mode 100755 model/audio/core/src/audio_parse.c create mode 100755 model/audio/core/src/codec_core.c create mode 100755 model/audio/core/test/unittest/common/audio_common_test.h create mode 100755 model/audio/core/test/unittest/common/audio_core_test.cpp create mode 100755 model/audio/core/test/unittest/common/audio_host_test.cpp create mode 100755 model/audio/core/test/unittest/common/audio_parse_test.cpp create mode 100755 model/audio/device/accessory/include/accessory_adapter.h create mode 100755 model/audio/device/accessory/src/accessory.c create mode 100755 model/audio/device/codec/include/codec_adapter.h create mode 100755 model/audio/device/codec/src/codec.c create mode 100755 model/audio/device/soc/include/dai_adapter.h create mode 100755 model/audio/device/soc/include/dsp_adapter.h create mode 100755 model/audio/device/soc/include/platform_adapter.h create mode 100755 model/audio/device/soc/src/dai.c create mode 100755 model/audio/device/soc/src/dsp.c create mode 100755 model/audio/device/soc/src/platform.c create mode 100755 model/audio/dispatch/include/audio_control_dispatch.h create mode 100755 model/audio/dispatch/include/audio_stream_dispatch.h create mode 100755 model/audio/dispatch/src/audio_control_dispatch.c create mode 100755 model/audio/dispatch/src/audio_stream_dispatch.c create mode 100755 model/audio/dispatch/test/unittest/common/audio_stream_dispatch_test.cpp create mode 100755 model/audio/sapm/include/audio_sapm.h create mode 100755 model/audio/sapm/src/audio_sapm.c create mode 100755 model/audio/sapm/test/unittest/common/audio_sapm_test.cpp create mode 100755 test/unittest/model/audio/include/audio_core_test.h create mode 100755 test/unittest/model/audio/include/audio_host_test.h create mode 100755 test/unittest/model/audio/include/audio_parse_test.h create mode 100755 test/unittest/model/audio/include/audio_sapm_test.h create mode 100755 test/unittest/model/audio/include/audio_stream_dispatch_test.h create mode 100755 test/unittest/model/audio/include/hdf_audio_test.h create mode 100755 test/unittest/model/audio/src/audio_core_test.c create mode 100755 test/unittest/model/audio/src/audio_host_test.c create mode 100755 test/unittest/model/audio/src/audio_parse_test.c create mode 100755 test/unittest/model/audio/src/audio_sapm_test.c create mode 100755 test/unittest/model/audio/src/audio_stream_dispatch_test.c create mode 100755 test/unittest/model/audio/src/hdf_audio_test.c diff --git a/model/audio/core/include/audio_control.h b/model/audio/core/include/audio_control.h new file mode 100755 index 000000000..8b2fab186 --- /dev/null +++ b/model/audio/core/include/audio_control.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2020-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. + */ + +#ifndef AUDIO_CONTROL_H +#define AUDIO_CONTROL_H + +#include "audio_types.h" +#include "hdf_dlist.h" + + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +struct AudioCtrlElemId { + const char *cardServiceName; + int32_t iface; + const char *itemName; /* ASCII name of item */ +}; + +struct AudioCtrlElemInfo { + struct AudioCtrlElemId id; + uint32_t count; /* count of values */ + int32_t type; /* R: value type - AUDIODRV_CTL_ELEM_IFACE_MIXER_* */ + int32_t min; /* R: minimum value */ + int32_t max; /* R: maximum value */ +}; + +struct AudioCtrlElemValue { + struct AudioCtrlElemId id; + int32_t value[2]; +}; + +struct AudioKcontrol; +typedef int32_t (*KconfigInfo_t)(struct AudioKcontrol *kcontrol, struct AudioCtrlElemInfo *elemInfo); +typedef int32_t (*KconfigGet_t)(struct AudioKcontrol *kcontrol, struct AudioCtrlElemValue *elemValue); +typedef int32_t (*KconfigPut_t)(struct AudioKcontrol *kcontrol, struct AudioCtrlElemValue *elemValue); + +/* mixer control */ +struct AudioMixerControl { + int32_t min; + int32_t max; + int32_t platformMax; + uint32_t mask; + uint32_t reg; + uint32_t rreg; /* right sound channel reg */ + uint32_t shift; + uint32_t rshift; /* right sound channel reg shift */ + uint32_t invert; +}; + +struct AudioKcontrol { + const char *name; /* ASCII name of item */ + int32_t iface; + KconfigInfo_t Info; + KconfigGet_t Get; + KconfigPut_t Put; + void *privateData; + void *pri; + unsigned long privateValue; + struct DListHead list; /* list of controls */ +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + +#endif diff --git a/model/audio/core/include/audio_core.h b/model/audio/core/include/audio_core.h new file mode 100755 index 000000000..03ac9ab57 --- /dev/null +++ b/model/audio/core/include/audio_core.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2020-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. + */ + +#ifndef AUDIO_CORE_H +#define AUDIO_CORE_H + +#include "audio_host.h" +#include "audio_control.h" +#include "codec_adapter.h" +#include "platform_adapter.h" +#include "dai_adapter.h" +#include "accessory_adapter.h" +#include "dsp_adapter.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +#define CHANNEL_MAX_NUM 2 +#define CHANNEL_MIN_NUM 1 + +#define AUDIO_DAI_LINK_COMPLETE 1 +#define AUDIO_DAI_LINK_UNCOMPLETE 0 + +#define AUDIO_DRIVER_LOG_ERR(fmt, arg...) do { \ + HDF_LOGE("[%s][line:%d]: " fmt, __func__, __LINE__, ##arg); \ + } while (0) + +#define AUDIO_DRIVER_LOG_INFO(fmt, arg...) do { \ + HDF_LOGI("[%s][line:%d]: " fmt, __func__, __LINE__, ##arg); \ + } while (0) + +#define AUDIO_DRIVER_LOG_WARNING(fmt, arg...) do { \ + HDF_LOGW("[%s][line:%d]: " fmt, __func__, __LINE__, ##arg); \ + } while (0) + +#define AUDIO_DRIVER_LOG_DEBUG(fmt, arg...) do { \ + HDF_LOGD("[%s][line:%d]: " fmt, __func__, __LINE__, ##arg); \ + } while (0) + +enum AudioDeviceType { + AUDIO_DAI_DEVICE, + AUDIO_DSP_DEVICE, + AUDIO_PLATFORM_DEVICE, + AUDIO_CODEC_DEVICE, + AUDIO_ACCESSORY_DEVICE, + AUDIO_DEVICE_BUTT, +}; + +enum PlayStatus { + STREAM_START = 4, + STREAM_STOP, +}; + +/* Dai registration interface */ +int32_t AudioSocRegisterDai(struct HdfDeviceObject *device, struct DaiData *data); +/* Platform registration interface */ +int32_t AudioSocRegisterPlatform(struct HdfDeviceObject *device, struct PlatformData *data); +/* Codec registration interface */ +int32_t AudioRegisterCodec(struct HdfDeviceObject *device, struct CodecData *codecData, struct DaiData *daiData); +int32_t AudioBindDaiLink(struct AudioCard *audioCard, struct AudioConfigData *configData); +int32_t AudioSocDeviceRegister(struct HdfDeviceObject *device, void *data, enum AudioDeviceType deviceType); +int32_t AudioSocRegisterDsp(struct HdfDeviceObject *device, struct DaiData *data); +int32_t AudioRegisterAccessory(struct HdfDeviceObject *device, struct AccessoryData *data, struct DaiData *daiData); +int32_t AudioUpdateRegBits(enum AudioDeviceType deviceType, void *device, + struct AudioMixerControl *mixerControl, int32_t value); +int32_t AudioAiaoUpdateRegBits(struct CodecDevice *codec, uint32_t reg, uint32_t mask, uint32_t shift, int32_t value); +struct CodecDevice *AudioKcontrolGetCodec(const struct AudioKcontrol *kcontrol); +struct AccessoryDevice *AudioKcontrolGetAccessory(const struct AudioKcontrol *kcontrol); +extern int32_t AudioAddControls(struct AudioCard *audioCard, + const struct AudioKcontrol *controls, int32_t controlMaxNum); +extern struct AudioKcontrol *AudioAddControl(const struct AudioCard *audioCard, const struct AudioKcontrol *ctl); +extern int32_t AudioCodecDeviceReadReg(struct CodecDevice *codec, uint32_t reg, uint32_t *val); +extern int32_t AudioAccessoryDeviceReadReg(struct AccessoryDevice *accessory, uint32_t reg, uint32_t *val); +extern int32_t AudioAiaoDeviceReadReg(struct CodecDevice *codec, uint32_t reg, uint32_t *val); + +extern int32_t AudioInfoCtrlSw(struct AudioKcontrol *kcontrol, struct AudioCtrlElemInfo *elemInfo); +extern int32_t AudioGetCtrlSw(struct AudioKcontrol *kcontrol, struct AudioCtrlElemValue *elemValue); +extern int32_t AudioPutCtrlSw(struct AudioKcontrol *kcontrol, struct AudioCtrlElemValue *elemValue); +extern int32_t AiaoGetCtrlSw(struct AudioKcontrol *kcontrol, struct AudioCtrlElemValue *elemValue); +extern int32_t AiaoPutCtrlSw(struct AudioKcontrol *kcontrol, struct AudioCtrlElemValue *elemValue); +int32_t AudioRegisterDeviceDsp(struct HdfDeviceObject *device, struct DspData *dspData, struct DaiData *DaiData); +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + +#endif /* AUDIO_CORE_H */ diff --git a/model/audio/core/include/audio_host.h b/model/audio/core/include/audio_host.h new file mode 100755 index 000000000..2ab9e3c57 --- /dev/null +++ b/model/audio/core/include/audio_host.h @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2020-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. + */ + +#ifndef AUDIO_HOST_H +#define AUDIO_HOST_H + +#include "hdf_base.h" +#include "hdf_dlist.h" +#include "hdf_device_desc.h" +#include "hdf_log.h" +#include "device_resource_if.h" +#include "osal_mem.h" +#include "osal_mutex.h" +#include "securec.h" +#include "audio_types.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +#define ADM_LOG_ERR(fmt, arg...) do { \ + HDF_LOGE("[%s][line:%d]: " fmt, __func__, __LINE__, ##arg); \ + } while (0) + +#define ADM_LOG_INFO(fmt, arg...) do { \ + HDF_LOGI("[%s][line:%d]: " fmt, __func__, __LINE__, ##arg); \ + } while (0) + +#define ADM_LOG_WARNING(fmt, arg...) do { \ + HDF_LOGW("[%s][line:%d]: " fmt, __func__, __LINE__, ##arg); \ + } while (0) + +#define ADM_LOG_DEBUG(fmt, arg...) do { \ + HDF_LOGD("[%s][line:%d]: " fmt, __func__, __LINE__, ##arg); \ + } while (0) + +#define BUFF_SIZE_MAX 64 + +#define AUDIO_LIST_HEAD_INIT(name) { &(name), &(name) } + +#define AUDIO_LIST_HEAD(name) \ + struct DListHead name = AUDIO_LIST_HEAD_INIT(name) + +struct AudioConfigData { + const char *cardServiceName; + const char *codecName; + const char *platformName; + const char *cpuDaiName; + const char *codecDaiName; + const char *accessoryName; + const char *accessoryDaiName; + const char *dspName; + const char *dspDaiName; +}; + +struct AudioCard { + struct AudioPcmRuntime *rtd; + struct AudioConfigData configData; + + /* Card-specific routes and components. */ + const struct AudioSapmComponent *sapmComponents; + int32_t sapmComponentsNum; + const struct AudioSapmRoute *sapmRoutes; + int32_t sapmRoutesNum; + + struct DListHead list; + struct DListHead controls; /* all controls for this card */ + struct DListHead components; /* all components for this card */ + struct DListHead paths; /* all paths for this card */ + struct DListHead sapmDirty; /* all dirty for this card */ +}; + +enum CriBuffStatus { + ENUM_CIR_BUFF_NORMAL = 1, + ENUM_CIR_BUFF_FULL, + ENUM_CIR_BUFF_EMPTY, +}; + +enum AudioStreamType { + AUDIO_CAPTURE_STREAM = 0, + AUDIO_RENDER_STREAM, +}; + +struct AudioPcmHwParams { + /* The stream type in a frame */ + enum AudioStreamType streamType; + /* The number of channels in a frame */ + uint32_t channels; + /* The number of frames per second */ + uint32_t rate; + /* The number of frames in a period */ + uint32_t periodSize; + /* The number of periods in a PCM */ + uint32_t periodCount; + /* The sample format of a PCM */ + enum AudioFormat format; /* < Audio data format. For details, see {@link AudioFormat}. */ + const char *cardServiceName; + uint32_t period; + uint32_t frameSize; + bool isBigEndian; + bool isSignedData; + uint32_t startThreshold; + uint32_t stopThreshold; + uint32_t silenceThreshold; +}; + +struct AudioHost { + struct IDeviceIoService service; + struct HdfDeviceObject *device; + void *priv; +}; + +struct AudioTxData { + enum CriBuffStatus status; + char *buf; /* buf address */ + unsigned long frames; /* frames number */ +}; + +struct AudioRxData { + enum CriBuffStatus status; + char *buf; + unsigned long bufSize; + unsigned long frames; /* frames number */ +}; + +struct AudioPcmRuntime { + /* runtime devices */ + struct CodecDevice *codec; + struct PlatformDevice *platform; + struct DaiDevice *codecDai; + struct DaiDevice *cpuDai; + struct DaiDevice *accessoryDai; + struct AccessoryDevice *accessory; + struct DspDevice *dsp; + struct DaiDevice *dspDai; + uint8_t complete; + uint32_t frameBits; + uint8_t *dmaArea; + unsigned long bufferSize; +}; + +struct AudioHost *AudioHostCreateAndBind(struct HdfDeviceObject *device); +void AudioHostDestroy(struct AudioHost *host); + +static inline struct HdfDeviceObject *AudioHostToDevice(struct AudioHost *host) +{ + return (host == NULL) ? NULL : host->device; +} + +static inline struct AudioHost *AudioHostFromDevice(struct HdfDeviceObject *device) +{ + return (device == NULL) ? NULL : (struct AudioHost *)device->service; +} + +/* Get a sound card instance */ +struct AudioCard *GetCardInstance(const char *serviceName); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + +#endif /* AUDIO_HOST_H */ diff --git a/model/audio/core/include/audio_parse.h b/model/audio/core/include/audio_parse.h new file mode 100755 index 000000000..e73e14c58 --- /dev/null +++ b/model/audio/core/include/audio_parse.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2020-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. + */ + +#ifndef AUDIO_PARSE_H +#define AUDIO_PARSE_H + +#include "audio_host.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +int32_t AudioFillConfigData(struct HdfDeviceObject *device, struct AudioConfigData *configData); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + +#endif /* AUDIO_PARSE_H */ diff --git a/model/audio/core/include/codec_core.h b/model/audio/core/include/codec_core.h new file mode 100755 index 000000000..a19378104 --- /dev/null +++ b/model/audio/core/include/codec_core.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2020-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. + */ + +#ifndef CODEC_CORE_H +#define CODEC_CORE_H + +#include "codec_adapter.h" +#include "audio_core.h" +#include "osal_io.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +int32_t CodecDeviceReadReg(struct CodecDevice *codec, uint32_t reg, uint32_t *value); +int32_t CodecDeviceWriteReg(struct CodecDevice *codec, uint32_t reg, uint32_t value); +int32_t AiaoDeviceReadReg(struct CodecDevice *codec, uint32_t reg, uint32_t *value); +int32_t AiaoDeviceWriteReg(struct CodecDevice *codec, uint32_t reg, uint32_t value); +int32_t CodecGetServiceName(struct HdfDeviceObject *device, const char **drvCodecName); +int32_t CodecGetDaiName(struct HdfDeviceObject *device, const char **drvDaiName); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + +#endif /* CODEC_CORE_H */ diff --git a/model/audio/core/src/audio_core.c b/model/audio/core/src/audio_core.c new file mode 100755 index 000000000..c05fb71e0 --- /dev/null +++ b/model/audio/core/src/audio_core.c @@ -0,0 +1,1038 @@ +/* + * Copyright (c) 2020-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_core.h" + +#define HDF_LOG_TAG audio_core + +AUDIO_LIST_HEAD(daiController); +AUDIO_LIST_HEAD(platformController); +AUDIO_LIST_HEAD(codecController); +AUDIO_LIST_HEAD(dspController); +AUDIO_LIST_HEAD(accessoryController); + +int32_t AudioSocRegisterDsp(struct HdfDeviceObject *device, struct DaiData *data) +{ + struct DaiDevice *dsp = NULL; + + if ((device == NULL) || (data == NULL)) { + ADM_LOG_ERR("Input params check error: device=%p, data=%p.", device, data); + return HDF_ERR_INVALID_OBJECT; + } + + dsp = (struct DaiDevice *)OsalMemCalloc(sizeof(*dsp)); + if (dsp == NULL) { + ADM_LOG_ERR("Malloc dsp device fail!"); + return HDF_ERR_MALLOC_FAIL; + } + + dsp->devDaiName = data->drvDaiName; + dsp->devData = data; + dsp->device = device; + DListInsertHead(&dsp->list, &daiController); + ADM_LOG_INFO("Register [%s] success.", dsp->devDaiName); + + return HDF_SUCCESS; +} + +int32_t AudioSocRegisterPlatform(struct HdfDeviceObject *device, struct PlatformData *data) +{ + struct PlatformDevice *platform = NULL; + + if ((device == NULL) || (data == NULL)) { + ADM_LOG_ERR("Input params check error: device=%p, data=%p.", device, data); + return HDF_ERR_INVALID_OBJECT; + } + + platform = (struct PlatformDevice *)OsalMemCalloc(sizeof(*platform)); + if (platform == NULL) { + ADM_LOG_ERR("Malloc platform device fail!"); + return HDF_ERR_MALLOC_FAIL; + } + + platform->devPlatformName = data->drvPlatformName; + platform->devData = data; + platform->device = device; + DListInsertHead(&platform->list, &platformController); + ADM_LOG_INFO("Register [%s] success.", platform->devPlatformName); + + return HDF_SUCCESS; +} + +int32_t AudioSocRegisterDai(struct HdfDeviceObject *device, struct DaiData *data) +{ + struct DaiDevice *dai = NULL; + + if ((device == NULL) || (data == NULL)) { + ADM_LOG_ERR("Input params check error: device=%p, data=%p.", device, data); + return HDF_ERR_INVALID_OBJECT; + } + + dai = (struct DaiDevice *)OsalMemCalloc(sizeof(*dai)); + if (dai == NULL) { + ADM_LOG_ERR("Malloc dai device fail!"); + return HDF_ERR_MALLOC_FAIL; + } + + dai->devDaiName = data->drvDaiName; + dai->devData = data; + dai->device = device; + DListInsertHead(&dai->list, &daiController); + ADM_LOG_INFO("Register [%s] success.", dai->devDaiName); + + return HDF_SUCCESS; +} + +int32_t AudioRegisterAccessory(struct HdfDeviceObject *device, struct AccessoryData *data, struct DaiData *daiData) +{ + struct AccessoryDevice *accessory = NULL; + int32_t ret; + + if (device == NULL || data == NULL || daiData == NULL) { + ADM_LOG_ERR("Input params check error: device=%p, data=%p, daiData=%p.", device, data, daiData); + return HDF_ERR_INVALID_OBJECT; + } + + accessory = (struct AccessoryDevice *)OsalMemCalloc(sizeof(*accessory)); + if (accessory == NULL) { + ADM_LOG_ERR("Malloc accessory device fail!"); + return HDF_ERR_MALLOC_FAIL; + } + + accessory->devAccessoryName = data->drvAccessoryName; + accessory->devData = data; + accessory->device = device; + + ret = AudioSocDeviceRegister(device, (void *)daiData, AUDIO_DAI_DEVICE); + if (ret != HDF_SUCCESS) { + OsalMemFree(accessory); + ADM_LOG_ERR("Register accessory device fail ret=%d", ret); + return HDF_ERR_IO; + } + DListInsertHead(&accessory->list, &accessoryController); + ADM_LOG_INFO("Register [%s] success.", accessory->devAccessoryName); + + return HDF_SUCCESS; +} + +int32_t AudioRegisterCodec(struct HdfDeviceObject *device, struct CodecData *codecData, struct DaiData *daiData) +{ + struct CodecDevice *codec = NULL; + int32_t ret; + + if ((device == NULL) || (codecData == NULL) || (daiData == NULL)) { + ADM_LOG_ERR("Input params check error: device=%p, codecData=%p, daiData=%p.", + device, codecData, daiData); + return HDF_ERR_INVALID_OBJECT; + } + + codec = (struct CodecDevice *)OsalMemCalloc(sizeof(*codec)); + if (codec == NULL) { + ADM_LOG_ERR("Malloc codec device fail!"); + return HDF_ERR_MALLOC_FAIL; + } + + OsalMutexInit(&codec->mutex); + codec->devCodecName = codecData->drvCodecName; + codec->devData = codecData; + codec->device = device; + + ret = AudioSocDeviceRegister(device, (void *)daiData, AUDIO_DAI_DEVICE); + if (ret != HDF_SUCCESS) { + OsalMemFree(codec); + ADM_LOG_ERR("Register dai device fail ret=%d", ret); + return HDF_ERR_IO; + } + DListInsertHead(&codec->list, &codecController); + ADM_LOG_INFO("Register [%s] success.", codec->devCodecName); + + return HDF_SUCCESS; +} + +int32_t AudioSocDeviceRegister(struct HdfDeviceObject *device, void *data, enum AudioDeviceType deviceType) +{ + struct PlatformData *platformData = NULL; + struct DaiData *daiData = NULL; + int32_t ret; + + if ((device == NULL) || (data == NULL) || (deviceType >= AUDIO_DEVICE_BUTT) || (deviceType < 0)) { + ADM_LOG_ERR("Input params check error: device=%p, data=%p, deviceType=%d.", + device, data, deviceType); + return HDF_ERR_INVALID_OBJECT; + } + + switch (deviceType) { + case AUDIO_DAI_DEVICE: { + daiData = (struct DaiData *)data; + ret = AudioSocRegisterDai(device, daiData); + if (ret != HDF_SUCCESS) { + ADM_LOG_ERR("Register dai device fail ret=%d", ret); + return HDF_FAILURE; + } + break; + } + case AUDIO_DSP_DEVICE: { + daiData = (struct DaiData *)data; + ret = AudioSocRegisterDsp(device, daiData); + if (ret != HDF_SUCCESS) { + ADM_LOG_ERR("Register dsp device fail ret=%d", ret); + return HDF_FAILURE; + } + break; + } + case AUDIO_PLATFORM_DEVICE: { + platformData = (struct PlatformData *)data; + ret = AudioSocRegisterPlatform(device, platformData); + if (ret != HDF_SUCCESS) { + ADM_LOG_ERR("Register dma device fail ret=%d", ret); + return HDF_FAILURE; + } + break; + } + default: { + ADM_LOG_ERR("Invalid device type."); + return HDF_FAILURE; + } + } + + return HDF_SUCCESS; +} + +void AudioSeekPlatformDevice(struct AudioPcmRuntime *rtd, const struct AudioConfigData *configData) +{ + const struct AudioConfigData *data = configData; + struct PlatformDevice *platform = NULL; + + if (rtd == NULL || data == NULL) { + ADM_LOG_ERR("Input params check error: rtd=%p, data=%p.", rtd, data); + return; + } + if (data->platformName == NULL) { + ADM_LOG_ERR("Input devicesName check error: data->platformName is NULL."); + return; + } + + DLIST_FOR_EACH_ENTRY(platform, &platformController, struct PlatformDevice, list) { + if (platform != NULL && platform->devPlatformName != NULL && + strcmp(platform->devPlatformName, data->platformName) == 0) { + rtd->platform = platform; + break; + } + } + return; +} + +void AudioSeekCpuDaiDevice(struct AudioPcmRuntime *rtd, const struct AudioConfigData *configData) +{ + const struct AudioConfigData *data = configData; + struct DaiDevice *cpuDai = NULL; + + if (rtd == NULL || data == NULL) { + ADM_LOG_ERR("Input params check error: rtd=%p, data=%p.", rtd, data); + return; + } + if (data->cpuDaiName == NULL) { + ADM_LOG_ERR("Input cpuDaiName check error: data->cpuDaiName is NULL."); + return; + } + + DLIST_FOR_EACH_ENTRY(cpuDai, &daiController, struct DaiDevice, list) { + if (cpuDai != NULL && cpuDai->devDaiName != NULL && strcmp(cpuDai->devDaiName, data->cpuDaiName) == 0) { + rtd->cpuDai = cpuDai; + break; + } + } + return; +} + +void AudioSeekCodecDevice(struct AudioPcmRuntime *rtd, const struct AudioConfigData *configData) +{ + const struct AudioConfigData *data = configData; + struct CodecDevice *codec = NULL; + struct DaiDevice *codecDai = NULL; + + if ((rtd == NULL) || (data == NULL)) { + ADM_LOG_ERR("Input params check error: rtd=%p, data=%p.", rtd, data); + return; + } + if (data->codecName == NULL || data->codecDaiName == NULL) { + ADM_LOG_ERR("Input devicesName check error: data->codecName=%p, data->codecDaiName=%p.", + data->codecName, data->codecDaiName); + return; + } + + DLIST_FOR_EACH_ENTRY(codec, &codecController, struct CodecDevice, list) { + if (codec != NULL && codec->devCodecName != NULL && strcmp(codec->devCodecName, data->codecName) == 0) { + rtd->codec = codec; + + DLIST_FOR_EACH_ENTRY(codecDai, &daiController, struct DaiDevice, list) { + if (codecDai != NULL && codecDai->device != NULL && codec->device == codecDai->device && + strcmp(codecDai->devDaiName, data->codecDaiName) == 0) { + rtd->codecDai = codecDai; + break; + } + } + break; + } + } + return; +} + +void AudioSeekAccessoryDevice(struct AudioPcmRuntime *rtd, const struct AudioConfigData *configData) +{ + const struct AudioConfigData *data = configData; + struct AccessoryDevice *accessory = NULL; + struct DaiDevice *accessoryDai = NULL; + + if (rtd == NULL || data == NULL) { + ADM_LOG_ERR("Input params check error: rtd=%p, data=%p.", rtd, data); + return; + } + if (data->accessoryName == NULL) { + ADM_LOG_ERR("Input devicesName check error: data->accessoryName is NULL."); + return; + } + + DLIST_FOR_EACH_ENTRY(accessory, &accessoryController, struct AccessoryDevice, list) { + if (accessory != NULL && accessory->devAccessoryName != NULL && + strcmp(accessory->devAccessoryName, data->accessoryName) == 0) { + rtd->accessory = accessory; + + DLIST_FOR_EACH_ENTRY(accessoryDai, &daiController, struct DaiDevice, list) { + if (accessoryDai != NULL && accessoryDai->device != NULL && accessory->device == accessoryDai->device && + strcmp(accessoryDai->devDaiName, data->accessoryDaiName) == 0) { + rtd->accessoryDai = accessoryDai; + break; + } + } + break; + } + } + return; +} + +void AudioSeekDspDevice(struct AudioPcmRuntime *rtd, const struct AudioConfigData *configData) +{ + const struct AudioConfigData *data = configData; + struct DspDevice *dsp = NULL; + struct DaiDevice *dspDai = NULL; + + if ((rtd == NULL) || (data == NULL)) { + ADM_LOG_ERR("Input params check error: rtd=%p, data=%p.", rtd, data); + return; + } + if (data->dspName == NULL || data->dspDaiName == NULL) { + ADM_LOG_ERR("Input devicesName check error: data->dspName=%p, data->dspDaiName=%p.", + data->codecName, data->codecDaiName); + return; + } + + DLIST_FOR_EACH_ENTRY(dsp, &dspController, struct DspDevice, list) { + if (dsp != NULL && dsp->devDspName != NULL && strcmp(dsp->devDspName, data->dspName) == 0) { + rtd->dsp = dsp; + DLIST_FOR_EACH_ENTRY(dspDai, &daiController, struct DaiDevice, list) { + if (dspDai != NULL && dspDai->device != NULL && dsp->device == dspDai->device && + strcmp(dspDai->devDaiName, data->dspDaiName) == 0) { + rtd->dspDai = dspDai; + break; + } + } + break; + } + } + return; +} + +int32_t AudioBindDaiLink(struct AudioCard *audioCard, struct AudioConfigData *configData) +{ + int32_t ret; + + if ((audioCard == NULL) || (configData == NULL)) { + ADM_LOG_ERR("Input params check error: audioCard=%p, configData=%p.", audioCard, configData); + return HDF_ERR_INVALID_OBJECT; + } + + audioCard->rtd = (struct AudioPcmRuntime *)OsalMemCalloc(sizeof(struct AudioPcmRuntime)); + if (audioCard->rtd == NULL) { + ADM_LOG_ERR("Malloc audioCard->rtd fail!"); + return HDF_ERR_MALLOC_FAIL; + } + + audioCard->rtd->complete = AUDIO_DAI_LINK_UNCOMPLETE; + + AudioSeekPlatformDevice(audioCard->rtd, configData); + AudioSeekCpuDaiDevice(audioCard->rtd, configData); + AudioSeekCodecDevice(audioCard->rtd, configData); + AudioSeekAccessoryDevice(audioCard->rtd, configData); + AudioSeekDspDevice(audioCard->rtd, configData); + if (!audioCard->rtd->codec && !audioCard->rtd->accessory) { + OsalMemFree(audioCard->rtd); + ret = HDF_FAILURE; + ADM_LOG_DEBUG("CODEC [%s] not registered!", configData->codecName); + } else if (!audioCard->rtd->codecDai && !audioCard->rtd->accessoryDai) { + OsalMemFree(audioCard->rtd); + ret = HDF_FAILURE; + ADM_LOG_DEBUG("CODEC DAI [%s] not registered!", configData->codecDaiName); + } else if (!audioCard->rtd->platform) { + OsalMemFree(audioCard->rtd); + ret = HDF_FAILURE; + ADM_LOG_DEBUG("Platform [%s] not registered!", configData->platformName); + } else if (!audioCard->rtd->cpuDai) { + OsalMemFree(audioCard->rtd); + ret = HDF_FAILURE; + ADM_LOG_DEBUG("CPU DAI [%s] not registered!", configData->cpuDaiName); + } else if (!audioCard->rtd->dsp) { + OsalMemFree(audioCard->rtd); + ret = HDF_FAILURE; + ADM_LOG_ERR("DSP [%s] not registered!", configData->dspName); + } else if (!audioCard->rtd->dspDai) { + OsalMemFree(audioCard->rtd); + ret = HDF_FAILURE; + ADM_LOG_ERR("DSP DAI [%s] not registered!", configData->dspDaiName); + } else { + audioCard->rtd->complete = AUDIO_DAI_LINK_COMPLETE; + ret = HDF_SUCCESS; + ADM_LOG_DEBUG("All devices register complete!"); + } + + return ret; +} + +int32_t AudioUpdateCodecRegBits(struct CodecDevice *codec, struct AudioMixerControl *mixerControl, int32_t value) +{ + int32_t ret; + uint32_t curValue; + int32_t mixerControlMask; + if (codec == NULL || codec->devData == NULL || codec->devData->Write == NULL || mixerControl == NULL) { + ADM_LOG_ERR("Invalid accessory param."); + return HDF_ERR_INVALID_OBJECT; + } + + value = value << mixerControl->shift; + mixerControlMask = mixerControl->mask << mixerControl->shift; + + OsalMutexLock(&codec->mutex); + ret = AudioCodecDeviceReadReg(codec, mixerControl->reg, &curValue); + if (ret != HDF_SUCCESS) { + OsalMutexUnlock(&codec->mutex); + ADM_LOG_ERR("Read reg fail ret=%d.", ret); + return HDF_FAILURE; + } + curValue = (curValue & ~mixerControlMask) | (value & mixerControlMask); + ret = codec->devData->Write(codec, mixerControl->reg, curValue); + if (ret != HDF_SUCCESS) { + OsalMutexUnlock(&codec->mutex); + ADM_LOG_ERR("Write reg fail ret=%d", ret); + return HDF_FAILURE; + } + OsalMutexUnlock(&codec->mutex); + + ADM_LOG_DEBUG("Success."); + return HDF_SUCCESS; +} + +int32_t AudioUpdateAccessoryRegBits(struct AccessoryDevice *accessory, + struct AudioMixerControl *mixerControl, int32_t value) +{ + int32_t ret; + uint32_t curValue; + int32_t mixerControlMask; + if (accessory == NULL || accessory->devData == NULL || + accessory->devData->Write == NULL || mixerControl == NULL) { + ADM_LOG_ERR("Invalid accessory param."); + return HDF_ERR_INVALID_OBJECT; + } + + value = value << mixerControl->shift; + mixerControlMask = mixerControl->mask << mixerControl->shift; + + OsalMutexLock(&accessory->mutex); + ret = AudioAccessoryDeviceReadReg(accessory, mixerControl->reg, &curValue); + if (ret != HDF_SUCCESS) { + OsalMutexUnlock(&accessory->mutex); + ADM_LOG_ERR("Read reg fail ret=%d", ret); + return HDF_FAILURE; + } + curValue = (curValue & ~mixerControlMask) | (value & mixerControlMask); + ret = accessory->devData->Write(accessory, mixerControl->reg, curValue); + if (ret != HDF_SUCCESS) { + OsalMutexUnlock(&accessory->mutex); + ADM_LOG_ERR("Write reg fail ret=%d", ret); + return HDF_FAILURE; + } + OsalMutexUnlock(&accessory->mutex); + + ADM_LOG_DEBUG("Success."); + return HDF_SUCCESS; +} + +int32_t AudioUpdateRegBits(enum AudioDeviceType deviceType, void *device, + struct AudioMixerControl *mixerControl, int32_t value) +{ + int32_t ret; + struct CodecDevice *codec = NULL; + struct AccessoryDevice *accessory = NULL; + ADM_LOG_DEBUG("Entry."); + + switch (deviceType) { + case AUDIO_CODEC_DEVICE: { + codec = (struct CodecDevice *)device; + ret = AudioUpdateCodecRegBits(codec, mixerControl, value); + break; + } + case AUDIO_ACCESSORY_DEVICE: { + accessory = (struct AccessoryDevice *)device; + ret = AudioUpdateAccessoryRegBits(accessory, mixerControl, value); + break; + } + default: { + ADM_LOG_ERR("Invalid device type."); + return HDF_FAILURE; + } + } + + return ret; +} + +int32_t AudioAiaoUpdateRegBits(struct CodecDevice *codec, uint32_t reg, uint32_t mask, uint32_t shift, int32_t value) +{ + int32_t ret; + uint32_t curValue; + ADM_LOG_DEBUG("Entry to update AIAO reg bits."); + + if (codec == NULL || codec->devData == NULL || codec->devData->AiaoWrite == NULL) { + ADM_LOG_ERR("Invalid AIAO codec param."); + return HDF_ERR_INVALID_OBJECT; + } + + value = value << shift; + mask = mask << shift; + + OsalMutexLock(&codec->mutex); + ret = AudioAiaoDeviceReadReg(codec, reg, &curValue); + if (ret != HDF_SUCCESS) { + OsalMutexUnlock(&codec->mutex); + ADM_LOG_ERR("Read AIAO reg fail ret=%d.", ret); + return HDF_FAILURE; + } + curValue = (curValue & ~mask) | (value & mask); + ret = codec->devData->AiaoWrite(codec, reg, curValue); + if (ret != HDF_SUCCESS) { + OsalMutexUnlock(&codec->mutex); + ADM_LOG_ERR("Write AIAO reg fail ret=%d", ret); + return HDF_FAILURE; + } + OsalMutexUnlock(&codec->mutex); + + ADM_LOG_DEBUG("Update AIAO reg bits successful."); + return HDF_SUCCESS; +} + +struct CodecDevice *AudioKcontrolGetCodec(const struct AudioKcontrol *kcontrol) +{ + struct AudioCard *audioCard = NULL; + if (kcontrol == NULL || kcontrol->pri == NULL) { + ADM_LOG_ERR("Input param kcontrol is NULL."); + return NULL; + } + + audioCard = (struct AudioCard *)(kcontrol->pri); + if (audioCard == NULL || audioCard->rtd == NULL) { + ADM_LOG_ERR("Get codec or rtd fail."); + return NULL; + } + + return audioCard->rtd->codec; +} + +struct AccessoryDevice *AudioKcontrolGetAccessory(const struct AudioKcontrol *kcontrol) +{ + struct AudioCard *audioCard = NULL; + if (kcontrol == NULL || kcontrol->pri == NULL) { + ADM_LOG_ERR("Input param kcontrol is NULL."); + return NULL; + } + + audioCard = (struct AudioCard *)(kcontrol->pri); + if (audioCard == NULL || audioCard->rtd == NULL) { + ADM_LOG_ERR("Get accessory or rtd fail."); + return NULL; + } + + return audioCard->rtd->accessory; +} + +struct AudioKcontrol *AudioAddControl(const struct AudioCard *audioCard, const struct AudioKcontrol *ctrl) +{ + struct AudioKcontrol *control = NULL; + + if ((audioCard == NULL) || (ctrl == NULL)) { + ADM_LOG_ERR("Input params check error: audioCard=%p, ctrl=%p.", audioCard, ctrl); + return NULL; + } + + control = (struct AudioKcontrol *)OsalMemCalloc(sizeof(*control)); + if (control == NULL) { + ADM_LOG_ERR("Malloc control fail!"); + return NULL; + } + control->name = ctrl->name; + control->iface = ctrl->iface; + control->Info = ctrl->Info; + control->Get = ctrl->Get; + control->Put = ctrl->Put; + control->pri = (void *)audioCard; + control->privateValue = ctrl->privateValue; + + return control; +} + +int32_t AudioAddControls(struct AudioCard *audioCard, const struct AudioKcontrol *controls, int32_t controlMaxNum) +{ + struct AudioKcontrol *control = NULL; + int32_t i; + ADM_LOG_DEBUG("Entry."); + + if ((audioCard == NULL) || (controls == NULL) || (controlMaxNum <= 0)) { + ADM_LOG_ERR("Input params check error: audioCard=%p, controls=%p, controlMaxNum=%d.", + audioCard, controls, controlMaxNum); + return HDF_FAILURE; + } + + for (i = 0; i < controlMaxNum; i++) { + control = AudioAddControl(audioCard, &controls[i]); + if (control == NULL) { + ADM_LOG_ERR("Add control fail!"); + return HDF_FAILURE; + } + DListInsertHead(&control->list, &audioCard->controls); + } + ADM_LOG_DEBUG("Success."); + return HDF_SUCCESS; +} + +int32_t AudioCodecDeviceReadReg(struct CodecDevice *codec, uint32_t reg, uint32_t *val) +{ + int32_t ret; + if (codec == NULL || codec->devData == NULL || codec->devData->Read == NULL || val == NULL) { + ADM_LOG_ERR("Input param codec is NULL."); + return HDF_FAILURE; + } + ret = codec->devData->Read(codec, reg, val); + if (ret != HDF_SUCCESS) { + ADM_LOG_ERR("Device read fail."); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +int32_t AudioAccessoryDeviceReadReg(struct AccessoryDevice *accessory, uint32_t reg, uint32_t *val) +{ + int32_t ret; + if (accessory == NULL || accessory->devData == NULL || accessory->devData->Read == NULL || val == NULL) { + ADM_LOG_ERR("Input param accessory is NULL."); + return HDF_FAILURE; + } + ret = accessory->devData->Read(accessory, reg, val); + if (ret != HDF_SUCCESS) { + ADM_LOG_ERR("Device read fail."); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +int32_t AudioAiaoDeviceReadReg(struct CodecDevice *codec, uint32_t reg, uint32_t *val) +{ + int32_t ret; + if (codec == NULL || codec->devData == NULL || codec->devData->AiaoRead == NULL || val == NULL) { + ADM_LOG_ERR("Input param codec is NULL."); + return HDF_FAILURE; + } + ret = codec->devData->AiaoRead(codec, reg, val); + if (ret != HDF_SUCCESS) { + ADM_LOG_ERR("Device read fail."); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +int32_t AudioInfoCtrlSw(struct AudioKcontrol *kcontrol, struct AudioCtrlElemInfo *elemInfo) +{ + struct AudioMixerControl *mixerCtrl = NULL; + + if (kcontrol == NULL || kcontrol->privateValue <= 0 || elemInfo == NULL) { + ADM_LOG_ERR("Input param kcontrol is NULL."); + return HDF_ERR_INVALID_OBJECT; + } + + elemInfo->count = CHANNEL_MIN_NUM; + mixerCtrl = (struct AudioMixerControl *)kcontrol->privateValue; + /* stereo */ + if (mixerCtrl->reg != mixerCtrl->rreg || mixerCtrl->shift != mixerCtrl->rshift) { + elemInfo->count = CHANNEL_MAX_NUM; + } + elemInfo->type = 1; /* volume type */ + elemInfo->min = mixerCtrl->min; + elemInfo->max = mixerCtrl->max; + + return HDF_SUCCESS; +} + +static int32_t AudioGetCtrlSwSubRReg(struct AudioKcontrol *kcontrol, struct AudioCtrlElemValue *elemValue, + enum AudioDeviceType deviceType, void *device) +{ + int32_t ret = HDF_FAILURE; + uint32_t rcurValue; + struct AudioMixerControl *mixerCtrl = NULL; + mixerCtrl = (struct AudioMixerControl *)kcontrol->privateValue; + struct CodecDevice *codec = (struct CodecDevice *)device; + struct AccessoryDevice *accessory = (struct AccessoryDevice *)device; + + if (mixerCtrl->reg != mixerCtrl->rreg || mixerCtrl->shift != mixerCtrl->rshift) { + if (codec != NULL && codec->devData != NULL && codec->devData->Read != NULL) { + ret = codec->devData->Read(codec, mixerCtrl->rreg, &rcurValue); + } else if (accessory != NULL && accessory->devData != NULL && accessory->devData->Read != NULL) { + ret = accessory->devData->Read(accessory, mixerCtrl->rreg, &rcurValue); + } + if (ret != HDF_SUCCESS) { + ADM_LOG_ERR("Device read fail."); + return HDF_FAILURE; + } + + if (mixerCtrl->reg == mixerCtrl->rreg) { + rcurValue = (rcurValue >> mixerCtrl->rshift) & mixerCtrl->mask; + } else { + rcurValue = (rcurValue >> mixerCtrl->shift) & mixerCtrl->mask; + } + if (rcurValue > mixerCtrl->max || rcurValue < mixerCtrl->min) { + ADM_LOG_ERR("Audio invalid rcurValue=%d", rcurValue); + return HDF_FAILURE; + } + if (mixerCtrl->invert) { + rcurValue = mixerCtrl->max - rcurValue; + } + elemValue->value[1] = rcurValue; + } + + return HDF_SUCCESS; +} + +static int32_t AudioGetCtrlSwSubReg(struct AudioKcontrol *kcontrol, struct AudioCtrlElemValue *elemValue, + enum AudioDeviceType deviceType, void *device) +{ + int32_t ret = HDF_FAILURE; + uint32_t curValue; + struct AudioMixerControl *mixerCtrl = NULL; + mixerCtrl = (struct AudioMixerControl *)kcontrol->privateValue; + struct CodecDevice *codec = (struct CodecDevice *)device; + struct AccessoryDevice *accessory = (struct AccessoryDevice *)device; + + if (codec != NULL && codec->devData != NULL && codec->devData->Read != NULL) { + ret = codec->devData->Read(codec, mixerCtrl->reg, &curValue); + } else if (accessory != NULL && accessory->devData != NULL && accessory->devData->Read != NULL) { + ret = accessory->devData->Read(accessory, mixerCtrl->reg, &curValue); + } + if (ret != HDF_SUCCESS) { + ADM_LOG_ERR("Device read fail."); + return HDF_FAILURE; + } + curValue = (curValue >> mixerCtrl->shift) & mixerCtrl->mask; + if (curValue > mixerCtrl->max || curValue < mixerCtrl->min) { + ADM_LOG_ERR("Audio invalid curValue=%d", curValue); + return HDF_FAILURE; + } + if (mixerCtrl->invert) { + curValue = mixerCtrl->max - curValue; + } + elemValue->value[0] = curValue; + return HDF_SUCCESS; +} + +int32_t AudioGetCtrlSw(struct AudioKcontrol *kcontrol, struct AudioCtrlElemValue *elemValue) +{ + enum AudioDeviceType deviceType; + struct CodecDevice *codec = NULL; + struct AccessoryDevice *accessory = NULL; + ADM_LOG_DEBUG("Entry to get audio ctrl switch."); + + if (kcontrol == NULL || kcontrol->privateValue <= 0 || elemValue == NULL) { + ADM_LOG_ERR("Audio input param kcontrol is NULL."); + return HDF_ERR_INVALID_OBJECT; + } + + codec = AudioKcontrolGetCodec(kcontrol); + accessory = AudioKcontrolGetAccessory(kcontrol); + if (codec != NULL && codec->devData != NULL && codec->devData->Read != NULL) { + deviceType = AUDIO_CODEC_DEVICE; + if (AudioGetCtrlSwSubReg(kcontrol, elemValue, deviceType, codec) || + AudioGetCtrlSwSubRReg(kcontrol, elemValue, deviceType, codec)) { + ADM_LOG_ERR("Audio Codec Get Ctrl Reg fail."); + return HDF_FAILURE; + } + } else { + deviceType = AUDIO_ACCESSORY_DEVICE; + if (AudioGetCtrlSwSubReg(kcontrol, elemValue, deviceType, accessory) || + AudioGetCtrlSwSubRReg(kcontrol, elemValue, deviceType, accessory)) { + ADM_LOG_ERR("Audio Accessory Get Ctrl Reg fail."); + return HDF_FAILURE; + } + } + + ADM_LOG_DEBUG("Get audio ctrl switch successful."); + return HDF_SUCCESS; +} + +static int32_t AiaoGetRightCtrlSw(struct CodecDevice *codec, struct AudioMixerControl *mixerCtrl, + struct AudioCtrlElemValue *elemValue) +{ + int ret; + uint32_t rcurValue; + if (mixerCtrl->reg != mixerCtrl->rreg || mixerCtrl->shift != mixerCtrl->rshift) { + ret = codec->devData->AiaoRead(codec, mixerCtrl->rreg, &rcurValue); + if (ret != HDF_SUCCESS) { + ADM_LOG_ERR("AIAO read rreg fail rcurValue=%d", rcurValue); + return HDF_FAILURE; + } + if (mixerCtrl->reg == mixerCtrl->rreg) { + rcurValue = (rcurValue >> mixerCtrl->rshift) & mixerCtrl->mask; + } else { + rcurValue = (rcurValue >> mixerCtrl->shift) & mixerCtrl->mask; + } + if (rcurValue > mixerCtrl->max) { + ADM_LOG_ERR("AIAO Invalid rcurValue=%d", rcurValue); + return HDF_FAILURE; + } + if (mixerCtrl->invert) { + rcurValue = mixerCtrl->max - rcurValue; + } + elemValue->value[1] = rcurValue; + } + + return HDF_SUCCESS; +} + +int32_t AiaoGetCtrlSw(struct AudioKcontrol *kcontrol, struct AudioCtrlElemValue *elemValue) +{ + int32_t ret; + struct CodecDevice *codec = NULL; + struct AudioMixerControl *mixerCtrl = NULL; + uint32_t curValue; + + ADM_LOG_DEBUG("Entry to get AIAO ctrl switch"); + + if (kcontrol == NULL || kcontrol->privateValue <= 0 || elemValue == NULL) { + ADM_LOG_ERR("AIAO input param is NULL."); + return HDF_ERR_INVALID_OBJECT; + } + + codec = AudioKcontrolGetCodec(kcontrol); + if (codec == NULL || codec->devData == NULL || codec->devData->AiaoRead == NULL) { + ADM_LOG_ERR("AIAO codec device is NULL."); + return HDF_FAILURE; + } + mixerCtrl = (struct AudioMixerControl *)kcontrol->privateValue; + ret = codec->devData->AiaoRead(codec, mixerCtrl->reg, &curValue); + if (ret != HDF_SUCCESS) { + ADM_LOG_ERR("AIAO read rreg fail rcurValue=%d", curValue); + return HDF_FAILURE; + } + curValue = (curValue >> mixerCtrl->shift) & mixerCtrl->mask; + if (curValue > mixerCtrl->max) { + ADM_LOG_ERR("AIAO invalid curValue=%d", curValue); + return HDF_FAILURE; + } + + if (mixerCtrl->invert) { + curValue = mixerCtrl->max - curValue; + } + elemValue->value[0] = curValue; + + ret = AiaoGetRightCtrlSw(codec, mixerCtrl, elemValue); + if (ret != HDF_SUCCESS) { + ADM_LOG_ERR("AIAO get right ctrl is fail"); + return HDF_FAILURE; + } + + ADM_LOG_DEBUG("Get AIAO ctrl switch successful."); + return HDF_SUCCESS; +} + +static int32_t AudioPutCtrlSwSub(struct AudioKcontrol *kcontrol, struct AudioCtrlElemValue *elemValue, + enum AudioDeviceType deviceType, void *device) +{ + int32_t value; + int32_t rvalue; + int32_t rshift; + int32_t ret; + struct AudioMixerControl *mixerCtrl = NULL; + mixerCtrl = (struct AudioMixerControl *)kcontrol->privateValue; + + value = elemValue->value[0]; + if (value < mixerCtrl->min || value > mixerCtrl->max) { + ADM_LOG_ERR("Audio invalid value=%d", value); + return HDF_ERR_INVALID_OBJECT; + } + + if (mixerCtrl->invert) { + value = mixerCtrl->max - value; + } + + ret = AudioUpdateRegBits(deviceType, device, mixerCtrl, value); + if (ret != HDF_SUCCESS) { + ADM_LOG_ERR("Audio update reg bits fail ret=%d", ret); + return HDF_FAILURE; + } + + if (mixerCtrl->reg != mixerCtrl->rreg || mixerCtrl->shift != mixerCtrl->rshift) { + rvalue = elemValue->value[1]; + if (rvalue < mixerCtrl->min || rvalue > mixerCtrl->max) { + ADM_LOG_ERR("Audio invalid rvalue=%d", rvalue); + return HDF_FAILURE; + } + if (mixerCtrl->invert) { + rvalue = mixerCtrl->max - rvalue; + } + if (mixerCtrl->reg == mixerCtrl->rreg) { + rshift = mixerCtrl->rshift; + } else { + rshift = mixerCtrl->shift; + } + mixerCtrl->shift = rshift; + ret = AudioUpdateRegBits(deviceType, device, mixerCtrl, rvalue); + if (ret != HDF_SUCCESS) { + ADM_LOG_ERR("Audio stereo update reg bits fail ret=%d", ret); + return HDF_FAILURE; + } + } + + return HDF_SUCCESS; +} + +int32_t AudioPutCtrlSw(struct AudioKcontrol *kcontrol, struct AudioCtrlElemValue *elemValue) +{ + void *device = NULL; + enum AudioDeviceType deviceType; + int32_t ret = HDF_FAILURE; + ADM_LOG_DEBUG("Entry to put audio ctrl switch."); + + if (kcontrol == NULL || (kcontrol->privateValue <= 0) || elemValue == NULL) { + ADM_LOG_ERR("Audio input param is NULL."); + return HDF_ERR_INVALID_OBJECT; + } + + struct CodecDevice *codec = AudioKcontrolGetCodec(kcontrol); + struct AccessoryDevice *accessory = AudioKcontrolGetAccessory(kcontrol); + if (codec != NULL && codec->devData != NULL && codec->devData->Write != NULL) { + deviceType = AUDIO_CODEC_DEVICE; + device = (void *)codec; + ret = AudioPutCtrlSwSub(kcontrol, elemValue, deviceType, device); + } else if (accessory != NULL && accessory->devData != NULL && accessory->devData->Write != NULL) { + deviceType = AUDIO_ACCESSORY_DEVICE; + device = (void *)accessory; + ret = AudioPutCtrlSwSub(kcontrol, elemValue, deviceType, device); + } + + if (ret != HDF_SUCCESS) { + ADM_LOG_ERR("Audio update fail ret=%d", ret); + return HDF_FAILURE; + } + + ADM_LOG_DEBUG("Put audio ctrl switch successful."); + return HDF_SUCCESS; +} + +int32_t AiaoPutCtrlSw(struct AudioKcontrol *kcontrol, struct AudioCtrlElemValue *elemValue) +{ + struct CodecDevice *codec = NULL; + struct AudioMixerControl *mixerCtrl = NULL; + int32_t value; + int32_t rvalue; + uint32_t rshift; + int32_t ret; + ADM_LOG_DEBUG("Entry to put AIAO ctrl switch."); + + if (kcontrol == NULL || (kcontrol->privateValue <= 0) || elemValue == NULL) { + ADM_LOG_ERR("AIAO input param is NULL."); + return HDF_ERR_INVALID_OBJECT; + } + + codec = AudioKcontrolGetCodec(kcontrol); + mixerCtrl = (struct AudioMixerControl *)kcontrol->privateValue; + value = elemValue->value[0]; + if (value < mixerCtrl->min || value > mixerCtrl->max) { + ADM_LOG_ERR("AIAO invalid value=%d", value); + return HDF_ERR_INVALID_OBJECT; + } + + if (mixerCtrl->invert) { + value = mixerCtrl->max - value; + } + + ret = AudioAiaoUpdateRegBits(codec, mixerCtrl->reg, mixerCtrl->mask, mixerCtrl->shift, value); + if (ret != HDF_SUCCESS) { + ADM_LOG_ERR("AIAO update reg bits fail ret=%d", ret); + return HDF_FAILURE; + } + + if (mixerCtrl->reg != mixerCtrl->rreg || mixerCtrl->shift != mixerCtrl->rshift) { + rvalue = elemValue->value[1]; + if (rvalue < mixerCtrl->min || rvalue > mixerCtrl->max) { + ADM_LOG_ERR("AIAO invalid rvalue=%d", rvalue); + return HDF_ERR_INVALID_OBJECT; + } + if (mixerCtrl->invert) { + rvalue = mixerCtrl->max - rvalue; + } + if (mixerCtrl->reg == mixerCtrl->rreg) { + rshift = mixerCtrl->rshift; + } else { + rshift = mixerCtrl->shift; + } + ret = AudioAiaoUpdateRegBits(codec, mixerCtrl->rreg, mixerCtrl->mask, rshift, rvalue); + if (ret != HDF_SUCCESS) { + ADM_LOG_ERR("AIAO stereo update reg bits fail ret=%d", ret); + return HDF_FAILURE; + } + } + + ADM_LOG_DEBUG("Put AIAO ctrl switch successful."); + return HDF_SUCCESS; +} + +int32_t AudioRegisterDeviceDsp(struct HdfDeviceObject *device, struct DspData *dspData, struct DaiData *DaiData) +{ + struct DspDevice *dspDev = NULL; + int32_t ret; + + if ((device == NULL) || (dspData == NULL) || (DaiData == NULL)) { + ADM_LOG_ERR("Input params check error: device=%p, dspData=%p, daiData=%p.", + device, dspData, DaiData); + return HDF_ERR_INVALID_OBJECT; + } + + dspDev = (struct DspDevice *)OsalMemCalloc(sizeof(*dspDev)); + if (dspDev == NULL) { + ADM_LOG_ERR("Malloc codec device fail!"); + return HDF_ERR_MALLOC_FAIL; + } + + dspDev->devDspName = dspData->drvDspName; + dspDev->devData = dspData; + dspDev->device = device; + + ret = AudioSocDeviceRegister(device, (void *)DaiData, AUDIO_DSP_DEVICE); + if (ret != HDF_SUCCESS) { + OsalMemFree(dspDev); + ADM_LOG_ERR("Register dai device fail ret=%d", ret); + return HDF_ERR_IO; + } + DListInsertHead(&dspDev->list, &dspController); + ADM_LOG_INFO("Register [%s] success.", dspDev->devDspName); + + return HDF_SUCCESS; +} diff --git a/model/audio/core/src/audio_host.c b/model/audio/core/src/audio_host.c new file mode 100755 index 000000000..f49a5f9d3 --- /dev/null +++ b/model/audio/core/src/audio_host.c @@ -0,0 +1,443 @@ +/* + * Copyright (c) 2020-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_host.h" +#include "audio_core.h" +#include "audio_parse.h" +#include "codec_adapter.h" + +#define HDF_LOG_TAG audio_host + +AUDIO_LIST_HEAD(cardManager); + +/* Get a sound card instance */ +struct AudioCard *GetCardInstance(const char *serviceName) +{ + struct AudioCard *audioCard = NULL; + + if (serviceName == NULL) { + ADM_LOG_ERR("serviceName is NULL."); + return NULL; + } + + DLIST_FOR_EACH_ENTRY(audioCard, &cardManager, struct AudioCard, list) { + if (strcmp(audioCard->configData.cardServiceName, serviceName) == 0) { + return audioCard; + } + } + return NULL; +} + +static int32_t AudioCodecDevInit(struct AudioCard *audioCard) +{ + if (audioCard == NULL) { + ADM_LOG_ERR("audioCard is NULL."); + return HDF_ERR_IO; + } + + ADM_LOG_DEBUG("entry."); + struct AudioPcmRuntime *rtd = NULL; + struct CodecDevice *codec = NULL; + rtd = audioCard->rtd; + if (rtd == NULL) { + ADM_LOG_ERR("rtd is NULL."); + return HDF_ERR_IO; + } + codec = rtd->codec; + if (codec == NULL || codec->devData == NULL || codec->devData->Init == NULL) { + ADM_LOG_ERR("codec is NULL."); + return HDF_ERR_IO; + } + /* codec initialization */ + int32_t ret = codec->devData->Init(audioCard, codec); + if (ret < 0) { + ADM_LOG_ERR("codec initialization fail ret=%d", ret); + return HDF_ERR_IO; + } + + ADM_LOG_INFO("success."); + return HDF_SUCCESS; +} + +static int32_t AudioAccessoryDevInit(struct AudioCard *audioCard) +{ + if (audioCard == NULL) { + ADM_LOG_ERR("audioCard is NULL."); + return HDF_ERR_IO; + } + + ADM_LOG_DEBUG("entry."); + struct AudioPcmRuntime *rtd = NULL; + struct AccessoryDevice *accessory = NULL; + rtd = audioCard->rtd; + if (rtd == NULL) { + ADM_LOG_ERR("rtd is NULL."); + return HDF_ERR_IO; + } + accessory = rtd->accessory; + if (accessory == NULL || accessory->devData == NULL || accessory->devData->AccessoryInit == NULL) { + ADM_LOG_ERR("accessory is NULL."); + return HDF_ERR_IO; + } + /* codec initialization */ + int32_t ret = accessory->devData->AccessoryInit(audioCard, accessory); + if (ret < 0) { + ADM_LOG_ERR("accessory initialization fail ret=%d", ret); + return HDF_ERR_IO; + } + + ADM_LOG_INFO("success."); + return HDF_SUCCESS; +} + +static int32_t AudioPlatformDevInit(struct AudioCard *audioCard) +{ + struct AudioPcmRuntime *rtd = NULL; + struct PlatformDevice *platform = NULL; + + if (audioCard == NULL) { + ADM_LOG_ERR("audioCard is NULL."); + return HDF_ERR_IO; + } + ADM_LOG_DEBUG("entry."); + + rtd = audioCard->rtd; + if (rtd == NULL) { + ADM_LOG_ERR("Platform rtd is NULL."); + return HDF_ERR_IO; + } + platform = rtd->platform; + if (platform == NULL || platform->devData == NULL || platform->devData->PlatformInit == NULL) { + ADM_LOG_ERR("platform is NULL."); + return HDF_ERR_IO; + } + /* platform initialization */ + int32_t ret = platform->devData->PlatformInit(audioCard, platform); + if (ret < 0) { + ADM_LOG_ERR("platform initialization fail ret=%d", ret); + return HDF_ERR_IO; + } + + ADM_LOG_INFO("success."); + return HDF_SUCCESS; +} + +static int32_t AudioCodecDaiDevInit(struct AudioCard *audioCard) +{ + struct AudioPcmRuntime *rtd = NULL; + struct DaiDevice *codecDai = NULL; + + if (audioCard == NULL) { + ADM_LOG_ERR("audioCard is NULL."); + return HDF_ERR_IO; + } + ADM_LOG_DEBUG("entry."); + + rtd = audioCard->rtd; + if (rtd == NULL) { + ADM_LOG_ERR("CodecDai rtd is NULL."); + return HDF_ERR_IO; + } + codecDai = rtd->codecDai; + if (codecDai == NULL || codecDai->devData == NULL || codecDai->devData->DaiInit == NULL) { + ADM_LOG_ERR("codecDai is NULL."); + return HDF_ERR_IO; + } + /* codec dai initialization */ + int32_t ret = codecDai->devData->DaiInit(audioCard, codecDai); + if (ret < 0) { + ADM_LOG_ERR("codec dai initialization fail ret=%d", ret); + return HDF_ERR_IO; + } + + ADM_LOG_INFO("success."); + return HDF_SUCCESS; +} + +static int32_t AudioAccessoryDaiDevInit(struct AudioCard *audioCard) +{ + struct AudioPcmRuntime *rtd = NULL; + struct DaiDevice *accessoryDai = NULL; + + if (audioCard == NULL) { + ADM_LOG_ERR("audioCard is NULL."); + return HDF_ERR_IO; + } + ADM_LOG_DEBUG("entry."); + + rtd = audioCard->rtd; + if (rtd == NULL) { + ADM_LOG_ERR("accessoryDai rtd is NULL."); + return HDF_ERR_IO; + } + accessoryDai = rtd->accessoryDai; + if (accessoryDai == NULL || accessoryDai->devData == NULL || accessoryDai->devData->DaiInit == NULL) { + ADM_LOG_ERR("accessoryDai is NULL."); + return HDF_ERR_IO; + } + /* codec dai initialization */ + int32_t ret = accessoryDai->devData->DaiInit(audioCard, accessoryDai); + if (ret < 0) { + ADM_LOG_ERR("accessory dai initialization fail ret=%d", ret); + return HDF_ERR_IO; + } + + ADM_LOG_INFO("success."); + return HDF_SUCCESS; +} + +static int32_t AudioCpuDaiDevInit(struct AudioCard *audioCard) +{ + struct AudioPcmRuntime *rtd = NULL; + struct DaiDevice *cpuDai = NULL; + + if (audioCard == NULL) { + ADM_LOG_ERR("audioCard is NULL."); + return HDF_ERR_IO; + } + ADM_LOG_DEBUG("entry."); + + rtd = audioCard->rtd; + if (rtd == NULL) { + ADM_LOG_ERR("cpuDai rtd is NULL."); + return HDF_ERR_IO; + } + cpuDai = rtd->cpuDai; + if (cpuDai == NULL || cpuDai->devData == NULL || cpuDai->devData->DaiInit == NULL) { + ADM_LOG_ERR("cpuDai is NULL."); + return HDF_ERR_IO; + } + /* cpu dai initialization */ + int32_t ret = cpuDai->devData->DaiInit(audioCard, cpuDai); + if (ret < 0) { + ADM_LOG_ERR("cpu dai initialization fail ret=%d", ret); + return HDF_ERR_IO; + } + + ADM_LOG_INFO("success."); + return HDF_SUCCESS; +} + +static int32_t AudioDspDaiDevInit(struct AudioCard *audioCard) +{ + struct AudioPcmRuntime *rtd = NULL; + struct DaiDevice *dspDai = NULL; + struct DspDevice *dsp = NULL; + int ret; + + if (audioCard == NULL) { + ADM_LOG_ERR("audioCard is NULL."); + return HDF_ERR_IO; + } + ADM_LOG_DEBUG("dsp init entry."); + + rtd = audioCard->rtd; + if (rtd == NULL) { + ADM_LOG_ERR("dspDai rtd is NULL."); + return HDF_ERR_IO; + } + + dspDai = rtd->dspDai; + if (dspDai == NULL || dspDai->devData == NULL || dspDai->devData->DaiInit == NULL) { + ADM_LOG_ERR("dsp is NULL."); + return HDF_ERR_IO; + } + + ret = dspDai->devData->DaiInit(audioCard, dspDai); + if (ret < 0) { + ADM_LOG_ERR("dsp dai initialization fail ret=%d", ret); + return HDF_ERR_IO; + } + + dsp = rtd->dsp; + if (dsp == NULL || dsp->devData == NULL || dsp->devData->DspInit == NULL) { + ADM_LOG_ERR("dsp is NULL."); + return HDF_ERR_IO; + } + + ret = dsp->devData->DspInit(dsp); + if (ret < 0) { + ADM_LOG_ERR("dsp initialization fail ret=%d", ret); + return HDF_ERR_IO; + } + + ADM_LOG_INFO("success."); + return HDF_SUCCESS; +} +static int32_t AudioInitDaiLink(struct AudioCard *audioCard) +{ + if (audioCard == NULL) { + ADM_LOG_ERR("audioCard is NULL."); + return HDF_ERR_IO; + } + ADM_LOG_DEBUG("entry."); + + if (AudioPlatformDevInit(audioCard) || AudioCpuDaiDevInit(audioCard)) { + ADM_LOG_ERR("Platform and CpuDai is NULL."); + return HDF_ERR_IO; + } + + if ((AudioCodecDevInit(audioCard) || AudioCodecDaiDevInit(audioCard)) && + (AudioAccessoryDevInit(audioCard) || AudioAccessoryDaiDevInit(audioCard))) { + ADM_LOG_ERR("codec is NULL."); + return HDF_ERR_IO; + } + + if (AudioDspDaiDevInit(audioCard)) { + ADM_LOG_ERR("Dsp Dai is NULL."); + return HDF_ERR_IO; + } + + ADM_LOG_DEBUG("success."); + return HDF_SUCCESS; +} + +void AudioCardDestroy(struct AudioCard *card) +{ + if (card == NULL) { + return; + } + if (card->rtd != NULL) { + OsalMemFree(card->rtd); + } + OsalMemFree(card); +} + +void AudioHostDestroy(struct AudioHost *host) +{ + if (host == NULL) { + return; + } + OsalMemFree(host); +} + +struct AudioHost *AudioHostCreateAndBind(struct HdfDeviceObject *device) +{ + struct AudioHost *audioHost = NULL; + + if (device == NULL) { + ADM_LOG_ERR("device is NULL!"); + return NULL; + } + + audioHost = (struct AudioHost *)OsalMemCalloc(sizeof(*audioHost)); + if (audioHost == NULL) { + ADM_LOG_ERR("Malloc audio host fail!"); + return NULL; + } + audioHost->device = device; + device->service = &audioHost->service; + return audioHost; +} + +/* HdfDriverEntry implementations */ +static int32_t AudioDriverBind(struct HdfDeviceObject *device) +{ + struct AudioHost *audioHost = NULL; + + ADM_LOG_DEBUG("entry."); + if (device == NULL) { + ADM_LOG_ERR("device is NULL."); + return HDF_ERR_INVALID_OBJECT; + } + + audioHost = AudioHostCreateAndBind(device); + if (audioHost == NULL) { + ADM_LOG_ERR("audioHost create failed!"); + return HDF_FAILURE; + } + + ADM_LOG_INFO("success."); + return HDF_SUCCESS; +} + +static int32_t AudioDriverInit(struct HdfDeviceObject *device) +{ + struct AudioCard *audioCard = NULL; + struct AudioHost *audioHost = NULL; + int32_t ret; + + ADM_LOG_DEBUG("entry."); + if (device == NULL) { + ADM_LOG_ERR("device is NULL."); + return HDF_ERR_INVALID_OBJECT; + } + audioHost = AudioHostFromDevice(device); + if (audioHost == NULL) { + ADM_LOG_ERR("audioHost is NULL."); + return HDF_FAILURE; + } + + audioCard = (struct AudioCard *)OsalMemCalloc(sizeof(*audioCard)); + if (audioCard == NULL) { + ADM_LOG_ERR("Malloc audioCard fail!"); + return HDF_FAILURE; + } + audioHost->priv = audioCard; + /* Get node information through HCS file */ + ret = AudioFillConfigData(device, &(audioCard->configData)); + if (ret != HDF_SUCCESS) { + ADM_LOG_ERR("AudioFillConfigData fail ret=%d", ret); + return HDF_ERR_IO; + } + + /* Bind specific codec、platform and dai device */ + AudioBindDaiLink(audioCard, &(audioCard->configData)); + if (!audioCard->rtd->complete) { + ADM_LOG_ERR("AudioBindDaiLink fail!"); + return HDF_ERR_IO; + } + + /* Initialize controls list */ + DListHeadInit(&audioCard->controls); + DListHeadInit(&audioCard->components); + DListHeadInit(&audioCard->paths); + DListHeadInit(&audioCard->sapmDirty); + /* Initialize hardware device */ + ret = AudioInitDaiLink(audioCard); + if (ret != HDF_SUCCESS) { + ADM_LOG_ERR("AudioInitDaiLink fail ret=%d", ret); + return HDF_ERR_IO; + } + + /* sound card added to list */ + DListInsertHead(&audioCard->list, &cardManager); + + ADM_LOG_INFO("success."); + return HDF_SUCCESS; +} + +static void AudioDriverRelease(struct HdfDeviceObject *device) +{ + struct AudioHost *audioHost = NULL; + + ADM_LOG_DEBUG("entry."); + if (device == NULL) { + ADM_LOG_ERR("device is NULL."); + return; + } + audioHost = AudioHostFromDevice(device); + if (audioHost == NULL) { + ADM_LOG_ERR("audioHost is NULL."); + return; + } + AudioCardDestroy(audioHost->priv); + AudioHostDestroy(audioHost); + + ADM_LOG_INFO("success."); +} + +/* HdfDriverEntry definitions */ +struct HdfDriverEntry g_audioDriverEntry = { + .moduleVersion = 1, + .moduleName = "HDF_AUDIO", + .Bind = AudioDriverBind, + .Init = AudioDriverInit, + .Release = AudioDriverRelease, +}; +HDF_INIT(g_audioDriverEntry); diff --git a/model/audio/core/src/audio_parse.c b/model/audio/core/src/audio_parse.c new file mode 100755 index 000000000..8ec926e11 --- /dev/null +++ b/model/audio/core/src/audio_parse.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2020-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_parse.h" + +#define HDF_LOG_TAG audio_parse + +int32_t AudioFillConfigData(struct HdfDeviceObject *device, struct AudioConfigData *configData) +{ + const struct DeviceResourceNode *node = NULL; + struct DeviceResourceIface *drsOps = NULL; + ADM_LOG_DEBUG("Entry."); + + if (device == NULL || configData == NULL) { + ADM_LOG_ERR("Input para check error: device=%p, configData=%p.", device, configData); + return HDF_FAILURE; + } + + node = device->property; + if (node == NULL) { + ADM_LOG_ERR("drs node is NULL."); + return HDF_FAILURE; + } + drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); + if (drsOps == NULL || drsOps->GetString == NULL) { + ADM_LOG_ERR("AudioFillConfigData: invalid drs ops fail!"); + return HDF_FAILURE; + } + + int32_t serviceRet = drsOps->GetString(node, "serviceName", &(configData->cardServiceName), 0); + int32_t codecRet = drsOps->GetString(node, "codecName", &(configData->codecName), 0); + int32_t platformRet = drsOps->GetString(node, "platformName", &(configData->platformName), 0); + int32_t cpuRet = drsOps->GetString(node, "cpuDaiName", &(configData->cpuDaiName), 0); + int32_t codeDaiRet = drsOps->GetString(node, "codecDaiName", &(configData->codecDaiName), 0); + int32_t dspRet = drsOps->GetString(node, "dspName", &(configData->dspName), 0); + int32_t dspDaiRet = drsOps->GetString(node, "dspDaiName", &(configData->dspDaiName), 0); + int32_t accessoryRet = drsOps->GetString(node, "accessoryName", &(configData->accessoryName), 0); + int32_t accessoryDaiRet = drsOps->GetString(node, "accessoryDaiName", &(configData->accessoryDaiName), 0); + if (serviceRet || codecRet || platformRet || cpuRet || codeDaiRet || + dspRet || dspDaiRet || accessoryRet || accessoryDaiRet) { + ADM_LOG_ERR("Read audioDeviceName fail: serviceRet=%d, codecRet=%d, platformRet=%d, cpuRet=%d, codeDaiRet=%d," + "dspRet=%d, dspDaiRet=%d, accessoryRet=%d, accessoryDaiRet=%s", + serviceRet, codecRet, platformRet, cpuRet, codeDaiRet, dspRet, + dspDaiRet, accessoryRet, accessoryDaiRet); + return HDF_FAILURE; + } + + ADM_LOG_DEBUG("Success! codecName = %s, platformName = %s, cpuDaiName = %s, codecDaiName = %s, " + "dspName = %s, dspDaiName = %s, accessoryName = %s, accessoryDaiName = %s.", + configData->codecName, configData->platformName, configData->cpuDaiName, + configData->codecDaiName, configData->dspName, configData->dspDaiName, + configData->accessoryName, configData->accessoryDaiName); + + return HDF_SUCCESS; +} diff --git a/model/audio/core/src/codec_core.c b/model/audio/core/src/codec_core.c new file mode 100755 index 000000000..ec9a1a4e9 --- /dev/null +++ b/model/audio/core/src/codec_core.c @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2020-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 "codec_core.h" + +#define HDF_LOG_TAG codec_core + +int32_t CodecDeviceReadReg(struct CodecDevice *codec, uint32_t reg, uint32_t *val) +{ + unsigned long acodecVir; + struct VirtualAddress *virtualAdd = NULL; + AUDIO_DRIVER_LOG_DEBUG("entry"); + + if ((codec == NULL) || (codec->device == NULL) || (val == NULL)) { + AUDIO_DRIVER_LOG_ERR("input param codec or codec->device is NULL."); + return HDF_ERR_INVALID_OBJECT; + } + virtualAdd = (struct VirtualAddress *)codec->device->priv; + if (virtualAdd == NULL) { + AUDIO_DRIVER_LOG_ERR("virtualAdd is NULL."); + return HDF_ERR_INVALID_OBJECT; + } + acodecVir = virtualAdd->acodecVir; + *val = OSAL_READL((void *)(acodecVir + reg)); + + AUDIO_DRIVER_LOG_DEBUG("success"); + return HDF_SUCCESS; +} + +int32_t CodecDeviceWriteReg(struct CodecDevice *codec, uint32_t reg, uint32_t value) +{ + unsigned long acodecVir; + struct VirtualAddress *virtualAdd = NULL; + AUDIO_DRIVER_LOG_DEBUG("entry"); + + if ((codec == NULL) || (codec->device == NULL)) { + AUDIO_DRIVER_LOG_ERR("param codec or codec->device is NULL."); + return HDF_ERR_INVALID_OBJECT; + } + + virtualAdd = (struct VirtualAddress *)codec->device->priv; + if (virtualAdd == NULL) { + AUDIO_DRIVER_LOG_ERR("virtualAdd is NULL."); + return HDF_ERR_INVALID_OBJECT; + } + + acodecVir = virtualAdd->acodecVir; + OSAL_WRITEL(value, (void *)(acodecVir + reg)); + + AUDIO_DRIVER_LOG_DEBUG("success"); + return HDF_SUCCESS; +} + +int32_t AiaoDeviceReadReg(struct CodecDevice *codec, uint32_t reg, uint32_t *val) +{ + unsigned long aiaoVir; + struct VirtualAddress *virtualAdd = NULL; + AUDIO_DRIVER_LOG_DEBUG("entry"); + + if ((codec == NULL) || (codec->device == NULL) || (val == NULL)) { + AUDIO_DRIVER_LOG_ERR("codec or codec->device is NULL."); + return HDF_ERR_INVALID_OBJECT; + } + + virtualAdd = (struct VirtualAddress *)codec->device->priv; + if (virtualAdd == NULL) { + AUDIO_DRIVER_LOG_ERR("virtualAdd is NULL."); + return HDF_ERR_INVALID_OBJECT; + } + + aiaoVir = virtualAdd->aiaoVir; + *val = OSAL_READL((void *)(aiaoVir + reg)); + + AUDIO_DRIVER_LOG_DEBUG("success"); + return HDF_SUCCESS; +} + +int32_t AiaoDeviceWriteReg(struct CodecDevice *codec, uint32_t reg, uint32_t value) +{ + unsigned long aiaoVir; + struct VirtualAddress *virtualAdd = NULL; + AUDIO_DRIVER_LOG_DEBUG("entry"); + + if ((codec == NULL) || (codec->device == NULL)) { + AUDIO_DRIVER_LOG_ERR("codec or codec->device is NULL."); + return HDF_ERR_INVALID_OBJECT; + } + virtualAdd = (struct VirtualAddress *)codec->device->priv; + if (virtualAdd == NULL) { + AUDIO_DRIVER_LOG_ERR("virtualAdd is NULL."); + return HDF_ERR_INVALID_OBJECT; + } + + aiaoVir = virtualAdd->aiaoVir; + OSAL_WRITEL(value, (void *)(aiaoVir + reg)); + + AUDIO_DRIVER_LOG_DEBUG("success"); + return HDF_SUCCESS; +} + +int32_t CodecGetServiceName(struct HdfDeviceObject *device, const char **drvCodecName) +{ + const struct DeviceResourceNode *node = NULL; + struct DeviceResourceIface *drsOps = NULL; + int32_t ret; + + if (device == NULL) { + AUDIO_DRIVER_LOG_ERR("input device para is nullptr."); + return HDF_FAILURE; + } + + node = device->property; + if (node == NULL) { + AUDIO_DRIVER_LOG_ERR("node instance is nullptr."); + return HDF_FAILURE; + } + drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); + if (drsOps == NULL || drsOps->GetString == NULL) { + AUDIO_DRIVER_LOG_ERR("from resouce get drsOps fail!"); + return HDF_FAILURE; + } + + ret = drsOps->GetString(node, "serviceName", drvCodecName, 0); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("read codecServiceName fail!"); + return ret; + } + + return HDF_SUCCESS; +} + +int32_t CodecGetDaiName(struct HdfDeviceObject *device, const char **drvDaiName) +{ + const struct DeviceResourceNode *node = NULL; + struct DeviceResourceIface *drsOps = NULL; + int32_t ret; + + if (device == NULL) { + AUDIO_DRIVER_LOG_ERR("input para is NULL."); + return HDF_FAILURE; + } + + node = device->property; + if (node == NULL) { + AUDIO_DRIVER_LOG_ERR("drs node is NULL."); + return HDF_FAILURE; + } + drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); + if (drsOps == NULL || drsOps->GetString == NULL) { + AUDIO_DRIVER_LOG_ERR("drs ops failed!"); + return HDF_FAILURE; + } + + ret = drsOps->GetString(node, "codecDaiName", drvDaiName, 0); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("read codecDaiName fail!"); + return ret; + } + + return HDF_SUCCESS; +} diff --git a/model/audio/core/test/unittest/common/audio_common_test.h b/model/audio/core/test/unittest/common/audio_common_test.h new file mode 100755 index 000000000..6cdde973f --- /dev/null +++ b/model/audio/core/test/unittest/common/audio_common_test.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2020-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. + */ + +#ifndef AUDIO_COMMON_TEST_H +#define AUDIO_COMMON_TEST_H + +#include "hdf_types.h" + +const int32_t g_testAudioType = 701; // 701 is TEST_AUDIO_TYPE + +enum { + TESTGETCODEC, + TESTGETCARDINSTANCE, + TESTHOSTDESTROY, + TESTGETCCNFIGDATA, + TESTREGISTERDAI, + TESTREGISTERPLATFORM, + TESTREGISTERCODEC, + TESTBINDDAILINK, + TESTDEVICEREGISTER, + TESTREGISTERDSP, + TESTREGISTERACCESSORY, + TESTUPDATEREGBITS, + TESTAIAOUPDATEREGBITS, + TESTKCONTROLGETCODEC, + TESTADDCONTROLS, + TESTADDCONTROL, + TESTDEVICEREADREG, + TESTAIAODEVICEREADREG, + TESTINFOCTRLSW, + TESTGETCTRLSW, + TESTPUTCTRLSW, + TESTAIAOGETCTRLSW, + TESTAIAOPUTCTRLSW, + TESTNEWCOMPONENT, + TESTADDROUTES, + TESTNEWCONTROLS, + TESTPOWERCOMPONET, + TESTREFRESHTIME, + TESTSTREAMDISPATCH, + TESTSTREAMDESTORY, +}; + +#endif /* AUDIO_COMMON_TEST_H */ diff --git a/model/audio/core/test/unittest/common/audio_core_test.cpp b/model/audio/core/test/unittest/common/audio_core_test.cpp new file mode 100755 index 000000000..9c5c9d176 --- /dev/null +++ b/model/audio/core/test/unittest/common/audio_core_test.cpp @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2020-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_common_test.h" +#include +#include "hdf_uhdf_test.h" + +using namespace testing::ext; + +class AudioCoreTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); +}; + +void AudioCoreTest::SetUpTestCase() +{ + HdfTestOpenService(); +} + +void AudioCoreTest::TearDownTestCase() +{ + HdfTestCloseService(); +} + +void AudioCoreTest::SetUp() +{ +} + +void AudioCoreTest::TearDown() +{ +} + +HWTEST_F(AudioCoreTest, AudioCoreTest_RegisterDai, TestSize.Level0) +{ + struct HdfTestMsg msg = {g_testAudioType, TESTREGISTERDAI, -1}; + EXPECT_EQ(0, HdfTestSendMsgToService(&msg)); +} + +HWTEST_F(AudioCoreTest, AudioCoreTest_RegisterPlatform, TestSize.Level0) +{ + struct HdfTestMsg msg = {g_testAudioType, TESTREGISTERPLATFORM, -1}; + EXPECT_EQ(0, HdfTestSendMsgToService(&msg)); +} + +HWTEST_F(AudioCoreTest, AudioCoreTest_RegisterCodec, TestSize.Level0) +{ + struct HdfTestMsg msg = {g_testAudioType, TESTREGISTERCODEC, -1}; + EXPECT_EQ(0, HdfTestSendMsgToService(&msg)); +} + +HWTEST_F(AudioCoreTest, AudioCoreTest_BindDaiLink, TestSize.Level0) +{ + struct HdfTestMsg msg = {g_testAudioType, TESTBINDDAILINK, -1}; + EXPECT_EQ(0, HdfTestSendMsgToService(&msg)); +} + +HWTEST_F(AudioCoreTest, AudioCoreTest_SocDeviceRegister, TestSize.Level0) +{ + struct HdfTestMsg msg = {g_testAudioType, TESTDEVICEREGISTER, -1}; + EXPECT_EQ(0, HdfTestSendMsgToService(&msg)); +} + +HWTEST_F(AudioCoreTest, AudioCoreTest_SocRegisterDsp, TestSize.Level0) +{ + struct HdfTestMsg msg = {g_testAudioType, TESTREGISTERDSP, -1}; + EXPECT_EQ(0, HdfTestSendMsgToService(&msg)); +} + +HWTEST_F(AudioCoreTest, AudioCoreTest_RegisterAccessory, TestSize.Level0) +{ + struct HdfTestMsg msg = {g_testAudioType, TESTREGISTERACCESSORY, -1}; + EXPECT_EQ(0, HdfTestSendMsgToService(&msg)); +} + +HWTEST_F(AudioCoreTest, AudioCoreTest_UpdateRegBits, TestSize.Level0) +{ + struct HdfTestMsg msg = {g_testAudioType, TESTUPDATEREGBITS, -1}; + EXPECT_EQ(0, HdfTestSendMsgToService(&msg)); +} + +HWTEST_F(AudioCoreTest, AudioCoreTest_AiaoUpdateRegBits, TestSize.Level0) +{ + struct HdfTestMsg msg = {g_testAudioType, TESTAIAOUPDATEREGBITS, -1}; + EXPECT_EQ(0, HdfTestSendMsgToService(&msg)); +} + +HWTEST_F(AudioCoreTest, AudioCoreTest_KcontrolGetCodec, TestSize.Level0) +{ + struct HdfTestMsg msg = {g_testAudioType, TESTKCONTROLGETCODEC, -1}; + EXPECT_EQ(0, HdfTestSendMsgToService(&msg)); +} + +HWTEST_F(AudioCoreTest, AudioCoreTest_AddControls, TestSize.Level0) +{ + struct HdfTestMsg msg = {g_testAudioType, TESTADDCONTROLS, -1}; + EXPECT_EQ(0, HdfTestSendMsgToService(&msg)); +} + +HWTEST_F(AudioCoreTest, AudioCoreTest_AddControl, TestSize.Level0) +{ + struct HdfTestMsg msg = {g_testAudioType, TESTADDCONTROL, -1}; + EXPECT_EQ(0, HdfTestSendMsgToService(&msg)); +} + +HWTEST_F(AudioCoreTest, AudioCoreTest_DeviceReadReg, TestSize.Level0) +{ + struct HdfTestMsg msg = {g_testAudioType, TESTDEVICEREADREG, -1}; + EXPECT_EQ(0, HdfTestSendMsgToService(&msg)); +} + +HWTEST_F(AudioCoreTest, AudioCoreTest_AiaoDeviceReadReg, TestSize.Level0) +{ + struct HdfTestMsg msg = {g_testAudioType, TESTAIAODEVICEREADREG, -1}; + EXPECT_EQ(0, HdfTestSendMsgToService(&msg)); +} + +HWTEST_F(AudioCoreTest, AudioCoreTest_InfoCtrlSw, TestSize.Level0) +{ + struct HdfTestMsg msg = {g_testAudioType, TESTINFOCTRLSW, -1}; + EXPECT_EQ(0, HdfTestSendMsgToService(&msg)); +} + +HWTEST_F(AudioCoreTest, AudioCoreTest_GetCtrlSw, TestSize.Level0) +{ + struct HdfTestMsg msg = {g_testAudioType, TESTGETCTRLSW, -1}; + EXPECT_EQ(0, HdfTestSendMsgToService(&msg)); +} + +HWTEST_F(AudioCoreTest, AudioCoreTest_PutCtrlSw, TestSize.Level0) +{ + struct HdfTestMsg msg = {g_testAudioType, TESTPUTCTRLSW, -1}; + EXPECT_EQ(0, HdfTestSendMsgToService(&msg)); +} + +HWTEST_F(AudioCoreTest, AudioCoreTest_AiaoGetCtrlSw, TestSize.Level0) +{ + struct HdfTestMsg msg = {g_testAudioType, TESTAIAOGETCTRLSW, -1}; + EXPECT_EQ(0, HdfTestSendMsgToService(&msg)); +} + +HWTEST_F(AudioCoreTest, AudioCoreTest_AiaoPutCtrlSw, TestSize.Level0) +{ + struct HdfTestMsg msg = {g_testAudioType, TESTAIAOPUTCTRLSW, -1}; + EXPECT_EQ(0, HdfTestSendMsgToService(&msg)); +} diff --git a/model/audio/core/test/unittest/common/audio_host_test.cpp b/model/audio/core/test/unittest/common/audio_host_test.cpp new file mode 100755 index 000000000..095b15480 --- /dev/null +++ b/model/audio/core/test/unittest/common/audio_host_test.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2020-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_common_test.h" +#include +#include "hdf_uhdf_test.h" + +using namespace testing::ext; + +class AudioHostTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); +}; + +void AudioHostTest::SetUpTestCase() +{ + HdfTestOpenService(); +} + +void AudioHostTest::TearDownTestCase() +{ + HdfTestCloseService(); +} + +void AudioHostTest::SetUp() +{ +} + +void AudioHostTest::TearDown() +{ +} + +HWTEST_F(AudioHostTest, AudioHostTest_GetCodec, TestSize.Level0) +{ + struct HdfTestMsg msg = {g_testAudioType, TESTGETCODEC, -1}; + EXPECT_EQ(0, HdfTestSendMsgToService(&msg)); +} + +HWTEST_F(AudioHostTest, AudioHostTest_GetAudioServiceName, TestSize.Level0) +{ + struct HdfTestMsg msg = {g_testAudioType, TESTGETCARDINSTANCE, -1}; + EXPECT_EQ(0, HdfTestSendMsgToService(&msg)); +} diff --git a/model/audio/core/test/unittest/common/audio_parse_test.cpp b/model/audio/core/test/unittest/common/audio_parse_test.cpp new file mode 100755 index 000000000..5e44e1839 --- /dev/null +++ b/model/audio/core/test/unittest/common/audio_parse_test.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2020-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_common_test.h" +#include +#include "hdf_uhdf_test.h" + +using namespace testing::ext; + +class AudioParseTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); +}; + +void AudioParseTest::SetUpTestCase() +{ + HdfTestOpenService(); +} + +void AudioParseTest::TearDownTestCase() +{ + HdfTestCloseService(); +} + +void AudioParseTest::SetUp() +{ +} + +void AudioParseTest::TearDown() +{ +} + +HWTEST_F(AudioParseTest, AudioParseTest_GetConfigData, TestSize.Level0) +{ + struct HdfTestMsg msg = {g_testAudioType, TESTGETCCNFIGDATA, -1}; + EXPECT_EQ(0, HdfTestSendMsgToService(&msg)); +} diff --git a/model/audio/device/accessory/include/accessory_adapter.h b/model/audio/device/accessory/include/accessory_adapter.h new file mode 100755 index 000000000..b75da35d4 --- /dev/null +++ b/model/audio/device/accessory/include/accessory_adapter.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2020-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. + */ + +#ifndef ACCESSORY_ADAPTER_H +#define ACCESSORY_ADAPTER_H + +#include "audio_host.h" +#include "audio_control.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +struct AccessoryDevice { + const char *devAccessoryName; + struct AccessoryData *devData; + struct HdfDeviceObject *device; + struct DListHead list; + struct OsalMutex mutex; +}; + +struct AudioAccessoryOps { + const char *devAccessoryName; + struct AccessoryData *devData; + struct HdfDeviceObject *device; + struct DListHead list; +}; + +struct AccessoryData { + const char *drvAccessoryName; + /* Accessory driver callbacks */ + int32_t (*AccessoryInit)(struct AudioCard *, const struct AccessoryDevice *device); + int32_t (*Read)(const struct AccessoryDevice *, uint32_t, uint32_t *); + int32_t (*Write)(const struct AccessoryDevice *, uint32_t, uint32_t); + + const struct AudioKcontrol *controls; + int numControls; +}; + +/* Accessory host is defined in accessory driver */ +struct AccessoryHost { + struct IDeviceIoService service; + struct HdfDeviceObject *device; + void *priv; +}; + + +int32_t ExternalCodecDeviceInit(struct AudioCard *audioCard, const struct AccessoryDevice *device); +int32_t ExternalCodecDeviceReadReg(const struct AccessoryDevice *codec, uint32_t reg, uint32_t *value); +int32_t ExternalCodecDeviceWriteReg(const struct AccessoryDevice *codec, uint32_t reg, uint32_t value); + +int32_t ExternalCodecDaiStartup(const struct AudioCard *card, const struct DaiDevice *device); +int32_t ExternalCodecDaiHwParams(const struct AudioCard *card, const struct AudioPcmHwParams *param, + const struct DaiDevice *device); +int32_t ExternalCodecDaiDeviceInit(const struct AudioCard *card, const struct DaiDevice *device); + + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + +#endif diff --git a/model/audio/device/accessory/src/accessory.c b/model/audio/device/accessory/src/accessory.c new file mode 100755 index 000000000..09ad410dd --- /dev/null +++ b/model/audio/device/accessory/src/accessory.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2020-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_core.h" +#include "accessory_adapter.h" +#include "audio_sapm.h" +#include "hdf_log.h" + +#define HDF_LOG_TAG "accessory" + +struct AccessoryData g_accessoryData = { + .AccessoryInit = ExternalCodecDeviceInit, + .Read = ExternalCodecDeviceReadReg, + .Write = ExternalCodecDeviceWriteReg, +}; + +struct AudioDaiOps g_accessoryDaiDeviceOps = { + .Startup = ExternalCodecDaiStartup, + .HwParams = ExternalCodecDaiHwParams, +}; + +struct DaiData g_accessoryDaiData = { + .drvDaiName = "accessory_dai", + .DaiInit = ExternalCodecDaiDeviceInit, + .ops = &g_accessoryDaiDeviceOps, +}; + +/* HdfDriverEntry */ +static int32_t GetServiceName(const struct HdfDeviceObject *device) +{ + const struct DeviceResourceNode *node = NULL; + struct DeviceResourceIface *drsOps = NULL; + int32_t ret; + if (device == NULL) { + AUDIO_DRIVER_LOG_ERR("input HdfDeviceObject object is nullptr."); + return HDF_FAILURE; + } + node = device->property; + if (node == NULL) { + AUDIO_DRIVER_LOG_ERR("get drs node is nullptr."); + return HDF_FAILURE; + } + drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); + if (drsOps == NULL || drsOps->GetString == NULL) { + AUDIO_DRIVER_LOG_ERR("drsOps or drsOps getString is null!"); + return HDF_FAILURE; + } + ret = drsOps->GetString(node, "serviceName", &g_accessoryData.drvAccessoryName, 0); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("read serviceName fail!"); + return ret; + } + return HDF_SUCCESS; +} + +/* HdfDriverEntry implementations */ +static int32_t AccessoryDriverInit(struct HdfDeviceObject *device) +{ + int32_t ret; + AUDIO_DRIVER_LOG_DEBUG("entry.\n"); + if (device == NULL) { + AUDIO_DRIVER_LOG_ERR("device is NULL."); + return HDF_ERR_INVALID_OBJECT; + } + ret = GetServiceName(device); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("get service name fail."); + return ret; + } + ret = AudioRegisterAccessory(device, &g_accessoryData, &g_accessoryDaiData); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("register dai fail."); + return ret; + } + AUDIO_DRIVER_LOG_DEBUG("Success!\n"); + return HDF_SUCCESS; +} + +/* HdfDriverEntry implementations */ +static int32_t AccessoryDriverBind(struct HdfDeviceObject *device) +{ + (void)device; + return HDF_SUCCESS; +} + +/* HdfDriverEntry definitions */ +struct HdfDriverEntry g_accessoryDriverEntry = { + .moduleVersion = 1, + .moduleName = "CODEC_TFA9879", + .Bind = AccessoryDriverBind, + .Init = AccessoryDriverInit, + .Release = NULL, +}; +HDF_INIT(g_accessoryDriverEntry); diff --git a/model/audio/device/codec/include/codec_adapter.h b/model/audio/device/codec/include/codec_adapter.h new file mode 100755 index 000000000..dd5fa502e --- /dev/null +++ b/model/audio/device/codec/include/codec_adapter.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2020-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. + */ + +#ifndef CODEC_ADAPTER_H +#define CODEC_ADAPTER_H + +#include "audio_host.h" +#include "audio_control.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +#define AUDIODRV_CTL_ELEM_IFACE_DAC 0 /* virtual dac device */ +#define AUDIODRV_CTL_ELEM_IFACE_ADC 1 /* virtual adc device */ +#define AUDIODRV_CTL_ELEM_IFACE_GAIN 2 /* virtual adc device */ +#define AUDIODRV_CTL_ELEM_IFACE_MIXER 3 /* virtual mixer device */ +#define AUDIODRV_CTL_ELEM_IFACE_ACODEC 4 /* Acodec device */ +#define AUDIODRV_CTL_ELEM_IFACE_PGA 5 /* PGA device */ +#define AUDIODRV_CTL_ELEM_IFACE_AIAO 6 /* AIAO device */ + +struct VirtualAddress { + unsigned long acodecVir; + unsigned long aiaoVir; +}; + +struct CodecDevice { + const char *devCodecName; + struct CodecData *devData; + struct HdfDeviceObject *device; + struct DListHead list; + struct OsalMutex mutex; +}; + +/* codec related definitions */ +struct CodecData { + const char *drvCodecName; + /* Codec driver callbacks */ + int32_t (*Init)(struct AudioCard *, struct CodecDevice *); + int32_t (*Read)(struct CodecDevice *, uint32_t, uint32_t *); + int32_t (*Write)(struct CodecDevice *, uint32_t, uint32_t); + int32_t (*AiaoRead)(struct CodecDevice *, uint32_t, uint32_t *); + int32_t (*AiaoWrite)(struct CodecDevice *, uint32_t, uint32_t); + const struct AudioKcontrol *controls; + int numControls; + const struct AudioSapmComponent *sapmComponents; + int numSapmComponent; + const struct AudioSapmRoute *sapmRoutes; + int numSapmRoutes; +}; + +/* Codec host is defined in codec driver */ +struct CodecHost { + struct IDeviceIoService service; + struct HdfDeviceObject *device; + unsigned long priv; + unsigned long aiaoPriv; +}; + +enum AudioRegParams { + PLAYBACK_VOLUME = 0, + CAPTURE_VOLUME, + PLAYBACK_MUTE, + CAPTURE_MUTE, + LEFT_GAIN, + RIGHT_GAIN, + EXTERNAL_CODEC_ENABLE, + INTERNALLY_CODEC_ENABLE, + RENDER_CHANNEL_MODE, + CAPTRUE_CHANNEL_MODE, +}; + +enum SapmRegParams { + LPGA_MIC = 0, + RPGA_MIC, + DACL2DACR, + DACR2DACL, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + +#endif /* CODEC_CORE_H */ diff --git a/model/audio/device/codec/src/codec.c b/model/audio/device/codec/src/codec.c new file mode 100755 index 000000000..54216a79c --- /dev/null +++ b/model/audio/device/codec/src/codec.c @@ -0,0 +1,643 @@ +/* + * Copyright (c) 2020-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 "codec_core.h" +#include "audio_core.h" +#include "audio_sapm.h" +#include "hi3516_aiao.h" +#include "hi3516_codec.h" +#include "osal_io.h" +#include "osal_irq.h" + +#define HDF_LOG_TAG codec + +#define ACODEC_CTRLREG0_ADDR 0x2c /* adcl,adcr, dacl, dacr power ctrl reg */ +#define ACODEC_DACREG1_ADDR 0x38 /* codec ctrl reg 3 */ +#define ACODEC_ADCREG0_ADDR 0x3c /* codec ctrl reg 4 */ +#define ACODEC_REG18_ADDR 0x48 /* codec ctrl reg 18 */ +#define ACODEC_ANACTRLREG0_ADDR 0x14 /* codec ana ctrl reg 0 */ +#define ACODEC_ANACTRLREG3_ADDR 0x20 /* codec ana ctrl reg 0 */ +#define ACODEC_CTRLREG1_ADDR 0x30 /* acodec ctrl reg1 */ +#define AIAO_RX_IF_ATTRI_ADDR 0x1000 /* aiao receive channel interface attribute */ +#define AIAO_TX_IF_ATTRI_ADDR 0x2000 /* aiao tranfer channel interface attribute */ +#define AIAO_TX_DSP_CTRL_ADDR 0x2004 + +static const struct AudioMixerControl g_audioRegParams[] = { + { + .reg = AIAO_TX_DSP_CTRL_ADDR, /* [0] output volume */ + .rreg = AIAO_TX_DSP_CTRL_ADDR, + .shift = 8, + .rshift = 8, + .min = 0x28, + .max = 0x7F, + .mask = 0x7F, + .invert = 0, + }, { + .reg = ACODEC_ADCREG0_ADDR, /* [1] input volume */ + .rreg = ACODEC_ADCREG0_ADDR, + .shift = 24, + .rshift = 24, + .min = 0x0, + .max = 0x57, + .mask = 0x7F, + .invert = 1, + }, { + .reg = ACODEC_DACREG1_ADDR, /* [2] output mute */ + .rreg = ACODEC_DACREG1_ADDR, + .shift = 31, + .rshift = 31, + .min = 0x0, + .max = 0x1, + .mask = 0x1, + .invert = 0, + }, { + .reg = ACODEC_ADCREG0_ADDR, /* [3] input mute */ + .rreg = ACODEC_ADCREG0_ADDR, + .shift = 31, + .rshift = 31, + .min = 0x0, + .max = 0x1, + .mask = 0x1, + .invert = 0, + }, { + .reg = ACODEC_ANACTRLREG3_ADDR, /* [4] left mic gain */ + .rreg = ACODEC_ANACTRLREG3_ADDR, + .shift = 16, + .rshift = 16, + .min = 0x0, + .max = 0xF, + .mask = 0x1F, + .invert = 0, + }, { + .reg = ACODEC_ANACTRLREG3_ADDR, /* [5] right mic gain */ + .rreg = ACODEC_ANACTRLREG3_ADDR, + .shift = 24, + .rshift = 24, + .min = 0x0, + .max = 0xF, + .mask = 0x1F, + .invert = 0, + }, { + .reg = ACODEC_REG18_ADDR, /* [6] external codec enable */ + .rreg = ACODEC_REG18_ADDR, + .shift = 1, + .rshift = 1, + .min = 0x0, + .max = 0x1, + .mask = 0x1, + .invert = 0, + }, { + .reg = ACODEC_REG18_ADDR, /* [7] internally codec enable */ + .rreg = ACODEC_REG18_ADDR, + .shift = 0, + .rshift = 0, + .min = 0x0, + .max = 0x1, + .mask = 0x1, + .invert = 0, + }, { + .reg = AIAO_TX_IF_ATTRI_ADDR, /* [8] aiao render channel mode */ + .rreg = AIAO_TX_IF_ATTRI_ADDR, + .shift = 16, + .rshift = 16, + .min = 0x0, + .max = 0x7, + .mask = 0x7, + .invert = 0, + }, { + .reg = AIAO_RX_IF_ATTRI_ADDR, /* [9] aiao capture channel mode */ + .rreg = AIAO_RX_IF_ATTRI_ADDR, + .shift = 16, + .rshift = 16, + .min = 0x0, + .max = 0x7, + .mask = 0x7, + .invert = 0, + }, +}; + +static const struct AudioKcontrol g_audioControls[] = { + { + .iface = AUDIODRV_CTL_ELEM_IFACE_DAC, + .name = "Master Playback Volume", + .Info = AudioInfoCtrlSw, + .Get = AiaoGetCtrlSw, + .Put = AiaoPutCtrlSw, + .privateValue = (unsigned long)&g_audioRegParams[PLAYBACK_VOLUME], + }, { + .iface = AUDIODRV_CTL_ELEM_IFACE_ADC, + .name = "Master Capture Volume", + .Info = AudioInfoCtrlSw, + .Get = AudioGetCtrlSw, + .Put = AudioPutCtrlSw, + .privateValue = (unsigned long)&g_audioRegParams[CAPTURE_VOLUME], + }, { + .iface = AUDIODRV_CTL_ELEM_IFACE_DAC, + .name = "Playback Mute", + .Info = AudioInfoCtrlSw, + .Get = AudioGetCtrlSw, + .Put = AudioPutCtrlSw, + .privateValue = (unsigned long)&g_audioRegParams[PLAYBACK_MUTE], + }, { + .iface = AUDIODRV_CTL_ELEM_IFACE_ADC, + .name = "Capture Mute", + .Info = AudioInfoCtrlSw, + .Get = AudioGetCtrlSw, + .Put = AudioPutCtrlSw, + .privateValue = (unsigned long)&g_audioRegParams[CAPTURE_MUTE], + }, { + .iface = AUDIODRV_CTL_ELEM_IFACE_GAIN, + .name = "Mic Left Gain", + .Info = AudioInfoCtrlSw, + .Get = AudioGetCtrlSw, + .Put = AudioPutCtrlSw, + .privateValue = (unsigned long)&g_audioRegParams[LEFT_GAIN], + }, { + .iface = AUDIODRV_CTL_ELEM_IFACE_GAIN, + .name = "Mic Right Gain", + .Info = AudioInfoCtrlSw, + .Get = AudioGetCtrlSw, + .Put = AudioPutCtrlSw, + .privateValue = (unsigned long)&g_audioRegParams[RIGHT_GAIN], + }, { + .iface = AUDIODRV_CTL_ELEM_IFACE_ACODEC, + .name = "External Codec Enable", + .Info = AudioInfoCtrlSw, + .Get = AudioGetCtrlSw, + .Put = AudioPutCtrlSw, + .privateValue = (unsigned long)&g_audioRegParams[EXTERNAL_CODEC_ENABLE], + }, { + .iface = AUDIODRV_CTL_ELEM_IFACE_ACODEC, + .name = "Internally Codec Enable", + .Info = AudioInfoCtrlSw, + .Get = AudioGetCtrlSw, + .Put = AudioPutCtrlSw, + .privateValue = (unsigned long)&g_audioRegParams[INTERNALLY_CODEC_ENABLE], + }, { + .iface = AUDIODRV_CTL_ELEM_IFACE_AIAO, + .name = "Render Channel Mode", + .Info = AudioInfoCtrlSw, + .Get = AiaoGetCtrlSw, + .Put = AiaoPutCtrlSw, + .privateValue = (unsigned long)&g_audioRegParams[RENDER_CHANNEL_MODE], + }, { + .iface = AUDIODRV_CTL_ELEM_IFACE_AIAO, + .name = "Captrue Channel Mode", + .Info = AudioInfoCtrlSw, + .Get = AiaoGetCtrlSw, + .Put = AiaoPutCtrlSw, + .privateValue = (unsigned long)&g_audioRegParams[CAPTRUE_CHANNEL_MODE], + }, +}; + +static const struct AudioMixerControl g_audioSapmRegParams[] = { + { + .reg = ACODEC_ANACTRLREG3_ADDR, /* LPGA MIC 0 -- connect MIC */ + .rreg = ACODEC_ANACTRLREG3_ADDR, + .shift = 23, + .rshift = 23, + .min = 0x0, + .max = 0x1, + .mask = 0x1, + .invert = 0, + }, { + .reg = ACODEC_ANACTRLREG3_ADDR, /* RPGA MIC 0 -- connect MIC */ + .rreg = ACODEC_ANACTRLREG3_ADDR, + .shift = 31, + .rshift = 31, + .min = 0x0, + .max = 0x1, + .mask = 0x1, + .invert = 0, + }, { + .reg = ACODEC_CTRLREG1_ADDR, /* [2] dacl to dacr mixer */ + .rreg = ACODEC_CTRLREG1_ADDR, + .shift = 27, + .rshift = 27, + .min = 0x0, + .max = 0x1, + .mask = 0x1, + .invert = 0, + }, { + .reg = ACODEC_CTRLREG1_ADDR, /* [3] dacr to dacl mixer */ + .rreg = ACODEC_CTRLREG1_ADDR, + .shift = 26, + .rshift = 26, + .min = 0x0, + .max = 0x1, + .mask = 0x1, + .invert = 0, + }, +}; + +static struct AudioKcontrol g_audioSapmDACLControls[] = { + { + .iface = AUDIODRV_CTL_ELEM_IFACE_DAC, + .name = "Dacl enable", + .Info = AudioInfoCtrlSw, + .Get = AudioSapmGetCtrlSw, + .Put = AudioSapmPutCtrlSw, + .privateValue = (unsigned long)&g_audioSapmRegParams[DACL2DACR], + }, +}; + +static struct AudioKcontrol g_audioSapmDACRControls[] = { + { + .iface = AUDIODRV_CTL_ELEM_IFACE_DAC, + .name = "Dacr enable", + .Info = AudioInfoCtrlSw, + .Get = AudioSapmGetCtrlSw, + .Put = AudioSapmPutCtrlSw, + .privateValue = (unsigned long)&g_audioSapmRegParams[DACR2DACL], + }, +}; + +static struct AudioKcontrol g_audioSapmLPGAControls[] = { + { + .iface = AUDIODRV_CTL_ELEM_IFACE_PGA, + .name = "LPGA MIC Switch", + .Info = AudioInfoCtrlSw, + .Get = AudioSapmGetCtrlSw, + .Put = AudioSapmPutCtrlSw, + .privateValue = (unsigned long)&g_audioSapmRegParams[LPGA_MIC], + }, +}; + +static struct AudioKcontrol g_audioSapmRPGAControls[] = { + { + .iface = AUDIODRV_CTL_ELEM_IFACE_PGA, + .name = "RPGA MIC Switch", + .Info = AudioInfoCtrlSw, + .Get = AudioSapmGetCtrlSw, + .Put = AudioSapmPutCtrlSw, + .privateValue = (unsigned long)&g_audioSapmRegParams[RPGA_MIC], + }, +}; + +static const struct AudioSapmComponent g_streamDomainComponents[] = { + { + .sapmType = AUDIO_SAPM_ADC, /* ADCL */ + .componentName = "ADCL", + .reg = ACODEC_ANACTRLREG3_ADDR, + .mask = 0x1, + .shift = 15, + .invert = 0, + }, { + .sapmType = AUDIO_SAPM_ADC, /* ADCR */ + .componentName = "ADCR", + .reg = ACODEC_ANACTRLREG3_ADDR, + .mask = 0x1, + .shift = 14, + .invert = 0, + }, { + .sapmType = AUDIO_SAPM_DAC, /* DACL */ + .componentName = "DACL", + .reg = ACODEC_ANACTRLREG0_ADDR, + .mask = 0x1, + .shift = 11, + .invert = 0, + }, { + .sapmType = AUDIO_SAPM_DAC, /* DACR */ + .componentName = "DACR", + .reg = ACODEC_ANACTRLREG0_ADDR, + .mask = 0x1, + .shift = 12, + .invert = 0, + }, { + .sapmType = AUDIO_SAPM_PGA, /* LPGA */ + .componentName = "LPGA", + .reg = ACODEC_ANACTRLREG3_ADDR, + .mask = 0x1, + .shift = 13, + .invert = 0, + .kcontrolNews = g_audioSapmLPGAControls, + .kcontrolsNum = ARRAY_SIZE(g_audioSapmLPGAControls), + }, { + .sapmType = AUDIO_SAPM_PGA, /* RPGA */ + .componentName = "RPGA", + .reg = ACODEC_ANACTRLREG3_ADDR, + .mask = 0x1, + .shift = 12, + .invert = 0, + .kcontrolNews = g_audioSapmRPGAControls, + .kcontrolsNum = ARRAY_SIZE(g_audioSapmRPGAControls), + }, { + .sapmType = AUDIO_SAPM_SPK, /* SPKL */ + .componentName = "SPKL", + .reg = AUDIO_SAPM_NOPM, + .mask = 0x1, + .shift = 0, + .invert = 0, + .kcontrolNews = g_audioSapmDACLControls, + .kcontrolsNum = ARRAY_SIZE(g_audioSapmDACLControls), + }, { + .sapmType = AUDIO_SAPM_SPK, /* SPKR */ + .componentName = "SPKR", + .reg = AUDIO_SAPM_NOPM, + .mask = 0x1, + .shift = 0, + .invert = 0, + .kcontrolNews = g_audioSapmDACRControls, + .kcontrolsNum = ARRAY_SIZE(g_audioSapmDACRControls), + }, { + .sapmType = AUDIO_SAPM_MIC, /* MIC */ + .componentName = "MIC", + .reg = AUDIO_SAPM_NOPM, + .mask = 0x1, + .shift = 0, + .invert = 0, + }, +}; + +static const struct AudioSapmRoute g_audioRoutes[] = { + { "SPKL", "Dacl enable", "DACL"}, + { "SPKR", "Dacr enable", "DACR"}, + + { "ADCL", NULL, "LPGA"}, + { "LPGA", "LPGA MIC Switch", "MIC"}, + + { "ADCR", NULL, "RPGA"}, + { "RPGA", "RPGA MIC Switch", "MIC"}, +}; + +static int32_t CodecDeviceInit(struct AudioCard *audioCard, struct CodecDevice *codec) +{ + const int innerCodecEnable = 7; + struct VirtualAddress *virtualAdd = NULL; + struct AudioMixerControl mixerCtrl = g_audioRegParams[innerCodecEnable]; + void *device = NULL; + + AUDIO_DRIVER_LOG_DEBUG("entry."); + if ((audioCard == NULL) || (audioCard->rtd == NULL || audioCard->rtd->codec == NULL) || (codec == NULL)) { + AUDIO_DRIVER_LOG_ERR("input para is NULL."); + return HDF_ERR_INVALID_OBJECT; + } + virtualAdd = (struct VirtualAddress *)OsalMemCalloc(sizeof(struct VirtualAddress)); + if (virtualAdd == NULL) { + AUDIO_DRIVER_LOG_ERR("virtualAdd fail!"); + return HDF_ERR_MALLOC_FAIL; + } + virtualAdd->acodecVir = (uintptr_t)OsalIoRemap(ACODEC_REG_BASE, ACODEC_MAX_REG_SIZE); + virtualAdd->aiaoVir = (uintptr_t)OsalIoRemap(AIAO_REG_BASE, AIAO_MAX_REG_SIZE); + codec->device->priv = virtualAdd; + + /* default inner codec */ + device = (void *)audioCard->rtd->codec; + if (AudioUpdateRegBits(AUDIO_CODEC_DEVICE, device, &mixerCtrl, 1) != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("update reg bits fail."); + return HDF_FAILURE; + } + + /* INIT */ + if (CodecHalSysInit() != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("CodecHalSysInit fail."); + return HDF_FAILURE; + } + + /* Acode init */ + AcodecDeviceInit(); + + if (AudioAddControls(audioCard, codec->devData->controls, codec->devData->numControls) != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("add controls fail."); + return HDF_FAILURE; + } + + if (AudioSapmNewComponents(audioCard, codec->devData->sapmComponents, + codec->devData->numSapmComponent) != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("new components fail."); + return HDF_FAILURE; + } + + if (AudioSapmAddRoutes(audioCard, codec->devData->sapmRoutes, + codec->devData->numSapmRoutes) != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("add route fail."); + return HDF_FAILURE; + } + + if (AudioSapmNewControls(audioCard) != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("add sapm controls fail."); + return HDF_FAILURE; + } + + AUDIO_DRIVER_LOG_DEBUG("success."); + return HDF_SUCCESS; +} + +int32_t CodecDaiDeviceInit(const struct AudioCard *card, const struct DaiDevice *device) +{ + if (device == NULL || device->devDaiName == NULL) { + AUDIO_DRIVER_LOG_ERR("input para is NULL."); + return HDF_FAILURE; + } + + AUDIO_DRIVER_LOG_DEBUG("codec dai device name: %s\n", device->devDaiName); + (void)card; + return HDF_SUCCESS; +} + +static int32_t FramatToBitWidth(enum AudioFormat format, unsigned int *bitWidth) +{ + switch (format) { + case AUDIO_FORMAT_PCM_8_BIT: + *bitWidth = BIT_WIDTH8; + break; + + case AUDIO_FORMAT_PCM_16_BIT: + *bitWidth = BIT_WIDTH16; + break; + + case AUDIO_FORMAT_PCM_24_BIT: + *bitWidth = BIT_WIDTH24; + break; + + case AUDIO_FORMAT_PCM_32_BIT: + *bitWidth = BIT_WIDTH32; + break; + + case AUDIO_FORMAT_AAC_MAIN: + case AUDIO_FORMAT_AAC_LC: + case AUDIO_FORMAT_AAC_LD: + case AUDIO_FORMAT_AAC_ELD: + case AUDIO_FORMAT_AAC_HE_V1: + case AUDIO_FORMAT_AAC_HE_V2: + break; + + default: + AUDIO_DRIVER_LOG_ERR("format: %d is not define.", format); + return HI_FAILURE; + break; + } + + return HI_SUCCESS; +} + + +int32_t CodecDaiHwParams(const struct AudioCard *card, + const struct AudioPcmHwParams *param, const struct DaiDevice *device) +{ + int ret; + unsigned int bitWidth; + (void)card; + (void)device; + + AUDIO_DRIVER_LOG_DEBUG("entry."); + if (param == NULL || param->cardServiceName == NULL) { + AUDIO_DRIVER_LOG_ERR("input para is NULL."); + return HDF_FAILURE; + } + + ret = FramatToBitWidth(param->format, &bitWidth); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("FramatToBitWidth: faile."); + return HDF_FAILURE; + } + + ret = AcodecSetI2s1Fs(param->rate); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("AcodecSetI2s1Fs fail."); + return HDF_FAILURE; + } + + ret = AcodecSetI2s1DataWidth(bitWidth); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("AcodecSetI2s1DataWidth fail."); + return HDF_FAILURE; + } + + AUDIO_DRIVER_LOG_DEBUG("channels = %d, rate = %d, periodSize = %d, \ + periodCount = %d, format = %d, cardServiceName = %s \n", + param->channels, param->rate, param->periodSize, + param->periodCount, (uint32_t)param->format, param->cardServiceName); + + AUDIO_DRIVER_LOG_DEBUG("success."); + return HDF_SUCCESS; +} + +int32_t CodecDaiStartup(const struct AudioCard *card, const struct DaiDevice *device) +{ + (void)card; + (void)device; + + return HDF_SUCCESS; +} + +struct CodecData g_codecData = { + .Init = CodecDeviceInit, + .Read = CodecDeviceReadReg, + .Write = CodecDeviceWriteReg, + .AiaoRead = AiaoDeviceReadReg, + .AiaoWrite = AiaoDeviceWriteReg, + .controls = g_audioControls, + .numControls = ARRAY_SIZE(g_audioControls), + .sapmComponents = g_streamDomainComponents, + .numSapmComponent = ARRAY_SIZE(g_streamDomainComponents), + .sapmRoutes = g_audioRoutes, + .numSapmRoutes = ARRAY_SIZE(g_audioRoutes), +}; + +struct AudioDaiOps g_codecDaiDeviceOps = { + .Startup = CodecDaiStartup, + .HwParams = CodecDaiHwParams, +}; + +struct DaiData g_codecDaiData = { + .DaiInit = CodecDaiDeviceInit, + .ops = &g_codecDaiDeviceOps, +}; + +/* HdfDriverEntry implementations */ +static int32_t CodecDriverBind(struct HdfDeviceObject *device) +{ + struct CodecHost *codecHost = NULL; + + AUDIO_DRIVER_LOG_DEBUG("entry!"); + + if (device == NULL) { + AUDIO_DRIVER_LOG_ERR("input para is NULL."); + return HDF_FAILURE; + } + + codecHost = (struct CodecHost *)OsalMemCalloc(sizeof(*codecHost)); + if (codecHost == NULL) { + AUDIO_DRIVER_LOG_ERR("malloc host fail!"); + return HDF_FAILURE; + } + + codecHost->device = device; + device->service = &codecHost->service; + + AUDIO_DRIVER_LOG_DEBUG("success!"); + return HDF_SUCCESS; +} + +static int32_t CodecDriverInit(struct HdfDeviceObject *device) +{ + int32_t ret; + + AUDIO_DRIVER_LOG_DEBUG("entry."); + if (device == NULL) { + AUDIO_DRIVER_LOG_ERR("device is NULL."); + return HDF_ERR_INVALID_OBJECT; + } + + ret = CodecGetServiceName(device, &g_codecData.drvCodecName); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("get codec service name fail."); + return ret; + } + + ret = CodecGetDaiName(device, &g_codecDaiData.drvDaiName); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("get codec dai name fail."); + return ret; + } + + ret = AudioRegisterCodec(device, &g_codecData, &g_codecDaiData); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("register dai fail."); + return ret; + } + + AUDIO_DRIVER_LOG_DEBUG("Success."); + return HDF_SUCCESS; +} + +static void CodecDriverRelease(struct HdfDeviceObject *device) +{ + struct CodecHost *codecHost = NULL; + struct VirtualAddress *virtualAdd = NULL; + + if (device == NULL) { + AUDIO_DRIVER_LOG_ERR("device is NULL"); + return; + } + + if (device->priv != NULL) { + virtualAdd = (struct VirtualAddress *)device->priv; + OsalIoUnmap((void *)((uintptr_t)(void*)&virtualAdd->acodecVir)); + OsalIoUnmap((void *)((uintptr_t)(void*)&virtualAdd->aiaoVir)); + OsalMemFree(device->priv); + } + + codecHost = (struct CodecHost *)device->service; + if (codecHost == NULL) { + HDF_LOGE("CodecDriverRelease: codecHost is NULL"); + return; + } + OsalMemFree(codecHost); +} + +/* HdfDriverEntry definitions */ +struct HdfDriverEntry g_codecDriverEntry = { + .moduleVersion = 1, + .moduleName = "CODEC_HI3516", + .Bind = CodecDriverBind, + .Init = CodecDriverInit, + .Release = CodecDriverRelease, +}; +HDF_INIT(g_codecDriverEntry); diff --git a/model/audio/device/soc/include/dai_adapter.h b/model/audio/device/soc/include/dai_adapter.h new file mode 100755 index 000000000..002f6ac7e --- /dev/null +++ b/model/audio/device/soc/include/dai_adapter.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2020-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. + */ + +#ifndef DAI_ADAPTER_H +#define DAI_ADAPTER_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +struct DaiDevice { + const char *devDaiName; + struct DaiData *devData; + struct HdfDeviceObject *device; + struct DListHead list; +}; + +struct AudioDaiOps { + int32_t (*Startup)(const struct AudioCard *, const struct DaiDevice *); + int32_t (*HwParams)(const struct AudioCard *, const struct AudioPcmHwParams *, const struct DaiDevice *); + int32_t (*Trigger)(const struct AudioCard *, int, const struct DaiDevice *); +}; + +struct DaiData { + const char *drvDaiName; + /* DAI driver callbacks */ + int32_t (*DaiInit)(const struct AudioCard *, const struct DaiDevice *); + /* ops */ + const struct AudioDaiOps *ops; +}; + +/* Dai host is defined in dai driver */ +struct DaiHost { + struct IDeviceIoService service; + struct HdfDeviceObject *device; + void *priv; + bool daiInitFlag; +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + +#endif diff --git a/model/audio/device/soc/include/dsp_adapter.h b/model/audio/device/soc/include/dsp_adapter.h new file mode 100755 index 000000000..e4c73aa56 --- /dev/null +++ b/model/audio/device/soc/include/dsp_adapter.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2020-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. + */ + +#ifndef DSP_ADAPTER_H +#define DSP_ADAPTER_H +#include "audio_host.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +struct DspDevice { + const char *devDspName; + struct DspData *devData; + struct HdfDeviceObject *device; + struct DListHead list; +}; + +struct AudioDspOps { + int32_t (*Startup)(const struct AudioCard *, const struct DspDevice *); + int32_t (*HwParams)(const struct AudioCard *, const struct AudioPcmHwParams *, const struct DspDevice *); + int32_t (*Trigger)(struct AudioCard *, int, struct DspDevice *); +}; + +struct DspData { + const char *drvDspName; + /* dsp driver callbacks */ + int32_t (*DspInit)(const struct DspDevice *device); + int32_t (*Read)(struct DspDevice *, uint8_t *, uint32_t); + int32_t (*Write)(struct DspDevice *, uint8_t *, uint32_t); + int32_t (*decode)(struct AudioCard *, void *, struct DspDevice *); + int32_t (*encode)(struct AudioCard *, void *, struct DspDevice *); + int32_t (*Equalizer)(struct AudioCard *, void *, struct DspDevice *); +}; + +/* Dsp host is defined in dsp driver */ +struct DspHost { + struct IDeviceIoService service; + struct HdfDeviceObject *device; + void *priv; +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + +#endif diff --git a/model/audio/device/soc/include/platform_adapter.h b/model/audio/device/soc/include/platform_adapter.h new file mode 100755 index 000000000..c24b9229b --- /dev/null +++ b/model/audio/device/soc/include/platform_adapter.h @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2020-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. + */ + +#ifndef PLATFORM_ADAPTER_H +#define PLATFORM_ADAPTER_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +#define I2S_IOCFG2_BASE1 0x0020 +#define I2S_IOCFG2_BASE2 0x0024 +#define I2S_IOCFG2_BASE3 0x0028 +#define I2S_IOCFG2_BASE4 0x002C +#define I2S_IOCFG2_BASE5 0x0030 + +#define I2S_IOCFG2_BASE1_VAL 0x663 +#define I2S_IOCFG2_BASE2_VAL 0x673 +#define I2S_IOCFG2_BASE3_VAL 0x573 +#define I2S_IOCFG2_BASE4_VAL 0x473 +#define I2S_IOCFG2_BASE5_VAL 0x433 + +#define I2S_IOCFG3_BASE1 0x44 +#define I2S_IOCFG3_BASE1_VAL 0x0600 + +#define GPIO_BASE1 0x2010 +#define GPIO_BASE2 0x2400 +#define GPIO_BASE3 0x2010 + +#define GPIO_BASE2_VAL 0x000000ff +#define GPIO_BASE3_VAL 0x00000000 + +#define IOCFG2_BASE_ADDR 0x112F0000 +#define IOCFG3_BASE_ADDR 0x10FF0000 +#define GPIO_BASE_ADDR 0x120D0000 +#define BASE_ADDR_REMAP_SIZE 0x10000 + +struct CircleBufInfo { + uint32_t cirBufSize; + uint32_t trafBufSize; + uint32_t period; + uint32_t periodSize; + uint32_t periodCount; + unsigned long phyAddr; + uint32_t *virtAddr; + uint32_t wbufOffSet; + uint32_t wptrOffSet; + uint32_t runStatus; + uint32_t chnId; + uint32_t enable; + struct OsalMutex buffMutex; +}; + +struct PcmInfo { + /* The number of channels in a frame */ + uint32_t channels; + /* The number of frames per second */ + uint32_t rate; + uint32_t bitWidth; + uint32_t frameSize; + bool isBigEndian; + bool isSignedData; + uint32_t startThreshold; + uint32_t stopThreshold; + uint32_t silenceThreshold; + uint32_t totalStreamSize; +}; + +/* platform related definitions */ +struct AudioPlatformOps { + int32_t (*HwParams)(const struct AudioCard *, const struct AudioPcmHwParams *); + int32_t (*RenderTrigger)(struct AudioCard *, int); + int32_t (*CaptureTrigger)(struct AudioCard *, int); + uint32_t (*Pointer)(struct AudioCard *); + int32_t (*Write)(const struct AudioCard *, struct AudioTxData *); + int32_t (*Read)(const struct AudioCard *, struct AudioRxData *); + int32_t (*RenderPrepare)(const struct AudioCard *); + int32_t (*CapturePrepare)(const struct AudioCard *); + int32_t (*RenderStart)(const struct AudioCard *); + int32_t (*CaptureStart)(const struct AudioCard *); + int32_t (*RenderStop)(const struct AudioCard *); + int32_t (*CaptureStop)(const struct AudioCard *); + int32_t (*RenderPause)(const struct AudioCard *); + int32_t (*CapturePause)(const struct AudioCard *); + int32_t (*RenderResume)(const struct AudioCard *); + int32_t (*CaptureResume)(const struct AudioCard *); +}; + +struct PlatformDevice { + const char *devPlatformName; + struct PlatformData *devData; + struct HdfDeviceObject *device; + struct DListHead list; +}; + +struct PlatformData { + const char *drvPlatformName; + /* platform driver callbacks */ + int32_t (*PlatformInit)(const struct AudioCard *, const struct PlatformDevice *); + /* pcm creation and destruction */ + int32_t (*PcmNew)(struct PlatformDevice *); + void (*PcmFree)(struct PlatformDevice *); + /* platform stream ops */ + struct AudioPlatformOps *ops; +}; + +/* Platform host is defined in platform driver */ +struct PlatformHost { + struct IDeviceIoService service; + struct HdfDeviceObject *device; + void *priv; + bool platformInitFlag; + struct CircleBufInfo renderBufInfo; + struct CircleBufInfo captureBufInfo; + struct PcmInfo pcmInfo; +}; + +static inline struct PlatformHost *PlatformHostFromDevice(struct HdfDeviceObject *device) +{ + return (device == NULL) ? NULL : (struct PlatformHost *)device->service; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + +#endif diff --git a/model/audio/device/soc/src/dai.c b/model/audio/device/soc/src/dai.c new file mode 100755 index 000000000..1c1c097d0 --- /dev/null +++ b/model/audio/device/soc/src/dai.c @@ -0,0 +1,335 @@ +/* + * Copyright (c) 2020-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_core.h" +#include "hi3516_aiao.h" +#include "hi3516_codec.h" +#include "osal_io.h" + +#define HDF_LOG_TAG dai + +/* HdfDriverEntry implementations */ +static int32_t DaiDriverBind(struct HdfDeviceObject *device) +{ + struct DaiHost *daiHost = NULL; + AUDIO_DRIVER_LOG_DEBUG("entry!"); + + if (device == NULL) { + AUDIO_DRIVER_LOG_ERR("input para is NULL."); + return HDF_FAILURE; + } + + daiHost = (struct DaiHost *)OsalMemCalloc(sizeof(*daiHost)); + if (daiHost == NULL) { + AUDIO_DRIVER_LOG_ERR("malloc host fail!"); + return HDF_FAILURE; + } + + daiHost->device = device; + daiHost->daiInitFlag = false; + device->service = &daiHost->service; + + AUDIO_DRIVER_LOG_DEBUG("success!"); + return HDF_SUCCESS; +} + +int32_t DaiDeviceInit(const struct AudioCard *audioCard, const struct DaiDevice *dai) +{ + int ret; + struct DaiHost *daiHost = NULL; + unsigned int chnId = 0; + + if (dai == NULL || dai->device == NULL || dai->devDaiName == NULL) { + AUDIO_DRIVER_LOG_ERR("dai is nullptr."); + return HDF_FAILURE; + } + AUDIO_DRIVER_LOG_DEBUG("cpu dai device name: %s\n", dai->devDaiName); + (void)audioCard; + + daiHost = (struct DaiHost *)dai->device->service; + if (daiHost == NULL) { + AUDIO_DRIVER_LOG_ERR("dai host is NULL."); + return HDF_FAILURE; + } + + if (daiHost->daiInitFlag == true) { + AUDIO_DRIVER_LOG_DEBUG("dai init complete!"); + return HDF_SUCCESS; + } + + ret = AiaoHalSysInit(); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("AiaoHalSysInit: fail."); + return HDF_FAILURE; + } + + ret = I2sCrgCfgInit(chnId); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("AiaoHalSysInit: fail."); + return HDF_FAILURE; + } + + daiHost->daiInitFlag = true; + + return HDF_SUCCESS; +} + +static int32_t CheckSampleRate(unsigned int sampleRates) +{ + bool checkSampleRate = (sampleRates == AUDIO_SAMPLE_RATE_8000 || + sampleRates == AUDIO_SAMPLE_RATE_12000 || + sampleRates == AUDIO_SAMPLE_RATE_11025 || + sampleRates == AUDIO_SAMPLE_RATE_16000 || + sampleRates == AUDIO_SAMPLE_RATE_22050 || + sampleRates == AUDIO_SAMPLE_RATE_24000 || + sampleRates == AUDIO_SAMPLE_RATE_32000 || + sampleRates == AUDIO_SAMPLE_RATE_44100 || + sampleRates == AUDIO_SAMPLE_RATE_48000 || + sampleRates == AUDIO_SAMPLE_RATE_64000 || + sampleRates == AUDIO_SAMPLE_RATE_96000); + if (checkSampleRate) { + return HDF_SUCCESS; + } else { + AUDIO_DRIVER_LOG_ERR("FramatToSampleRate fail: Invalid sampling rate: %d.", sampleRates); + return HI_FAILURE; + } +} + +static int32_t FramatToBitWidth(enum AudioFormat format, unsigned int *bitWidth) +{ + switch (format) { + case AUDIO_FORMAT_PCM_16_BIT: + *bitWidth = BIT_WIDTH16; + break; + + case AUDIO_FORMAT_PCM_24_BIT: + *bitWidth = BIT_WIDTH24; + break; + + default: + AUDIO_DRIVER_LOG_ERR("format: %d is not define.", format); + return HI_FAILURE; + break; + } + + return HDF_SUCCESS; +} + +int32_t AiSetClkAttr(struct PlatformHost *platformHost, const struct AudioPcmHwParams *param) +{ + int ret; + unsigned int bitWidth; + + if (platformHost == NULL) { + AUDIO_DRIVER_LOG_ERR("platform host is NULL."); + return HDF_FAILURE; + } + + if (param == NULL) { + AUDIO_DRIVER_LOG_ERR("param is NULL."); + return HDF_FAILURE; + } + + ret = FramatToBitWidth(param->format, &bitWidth); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("FramatToBitWidth: fail."); + return HDF_FAILURE; + } + platformHost->pcmInfo.bitWidth = bitWidth; + + ret = AipSetSysCtlReg(platformHost->captureBufInfo.chnId, param->channels, bitWidth, param->rate); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("AiSetClkAttr: fail."); + return HDF_FAILURE; + } + + ret = AipSetAttr(platformHost->captureBufInfo.chnId, param->channels, bitWidth); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("AiSetClkAttr: fail."); + return HDF_FAILURE; + } + + return HDF_SUCCESS; +} + +int32_t AoSetClkAttr(struct PlatformHost *platformHost, const struct AudioPcmHwParams *param) +{ + int ret; + unsigned int bitWidth; + + if (platformHost == NULL) { + AUDIO_DRIVER_LOG_ERR("platform host is nullptr."); + return HDF_FAILURE; + } + + if (param == NULL) { + AUDIO_DRIVER_LOG_ERR("param is nullptr."); + return HDF_FAILURE; + } + + ret = FramatToBitWidth(param->format, &bitWidth); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("FramatToBitWidth: fail."); + return HDF_FAILURE; + } + platformHost->pcmInfo.bitWidth = bitWidth; + + ret = AopSetSysCtlReg(platformHost->renderBufInfo.chnId, param->channels, bitWidth, param->rate); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("PlatformAopSetSysCtl: fail."); + return HDF_FAILURE; + } + + ret = AopSetAttr(platformHost->renderBufInfo.chnId, param->channels, bitWidth); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("PlatformAopSetAttrReg: fail."); + return HDF_FAILURE; + } + + AUDIO_DRIVER_LOG_DEBUG("bitWidth: %d.", bitWidth); + + return HDF_SUCCESS; +} + +int32_t DaiHwParams(const struct AudioCard *card, const struct AudioPcmHwParams *param, const struct DaiDevice *device) +{ + struct PlatformHost *platformHost = NULL; + int ret; + (void)device; + + AUDIO_DRIVER_LOG_DEBUG("entry."); + + if (card == NULL || card->rtd == NULL || card->rtd->platform == NULL || + param == NULL || param->cardServiceName == NULL) { + AUDIO_DRIVER_LOG_ERR("input para is nullptr."); + return HDF_FAILURE; + } + + ret = CheckSampleRate(param->rate); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("CheckSampleRate: fail."); + return HDF_FAILURE; + } + + platformHost = PlatformHostFromDevice(card->rtd->platform->device); + if (platformHost == NULL) { + AUDIO_DRIVER_LOG_ERR("platformHost is nullptr."); + return HDF_FAILURE; + } + + if (param->streamType == AUDIO_RENDER_STREAM) { + ret = AoSetClkAttr(platformHost, param); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("AoSetClkAttr: fail."); + return HDF_FAILURE; + } + } else if (param->streamType == AUDIO_CAPTURE_STREAM) { + ret = AiSetClkAttr(platformHost, param); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("AiSetClkAttr: fail."); + return HDF_FAILURE; + } + } else { + AUDIO_DRIVER_LOG_ERR("param streamType is invalid."); + return HDF_FAILURE; + } + + AUDIO_DRIVER_LOG_DEBUG("channels = %d, rate = %d, periodSize = %d, \ + periodCount = %d, format = %d, cardServiceName = %s \n", + param->channels, param->rate, param->periodSize, + param->periodCount, (uint32_t)param->format, param->cardServiceName); + + AUDIO_DRIVER_LOG_DEBUG("success."); + return HDF_SUCCESS; +} + +int32_t DaiTrigger(const struct AudioCard *card, int cmd, const struct DaiDevice *device) +{ + (void)card; + (void)device; + (void)cmd; + + return HDF_SUCCESS; +} + +struct AudioDaiOps g_daiDeviceOps = { + .HwParams = DaiHwParams, + .Trigger = DaiTrigger, +}; + +struct DaiData g_daiData = { + .DaiInit = DaiDeviceInit, + .ops = &g_daiDeviceOps, +}; + +static int32_t DaiGetServiceName(const struct HdfDeviceObject *device) +{ + const struct DeviceResourceNode *node = NULL; + struct DeviceResourceIface *drsOps = NULL; + int32_t ret; + + if (device == NULL) { + AUDIO_DRIVER_LOG_ERR("input para is nullptr."); + return HDF_FAILURE; + } + + node = device->property; + if (node == NULL) { + AUDIO_DRIVER_LOG_ERR("drs node is nullptr."); + return HDF_FAILURE; + } + drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); + if (drsOps == NULL || drsOps->GetString == NULL) { + AUDIO_DRIVER_LOG_ERR("invalid drs ops fail!"); + return HDF_FAILURE; + } + + ret = drsOps->GetString(node, "serviceName", &g_daiData.drvDaiName, 0); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("read serviceName fail!"); + return ret; + } + + return HDF_SUCCESS; +} + +static int32_t DaiDriverInit(struct HdfDeviceObject *device) +{ + int32_t ret; + AUDIO_DRIVER_LOG_DEBUG("entry.\n"); + + if (device == NULL) { + AUDIO_DRIVER_LOG_ERR("device is nullptr."); + return HDF_ERR_INVALID_OBJECT; + } + + ret = DaiGetServiceName(device); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("get service name fail."); + return ret; + } + + ret = AudioSocDeviceRegister(device, (void *)&g_daiData, AUDIO_DAI_DEVICE); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("register dai fail."); + return ret; + } + + AUDIO_DRIVER_LOG_DEBUG("success.\n"); + return HDF_SUCCESS; +} + +/* HdfDriverEntry definitions */ +struct HdfDriverEntry g_daiDriverEntry = { + .moduleVersion = 1, + .moduleName = "DAI_HI3516", + .Bind = DaiDriverBind, + .Init = DaiDriverInit, + .Release = NULL, +}; +HDF_INIT(g_daiDriverEntry); diff --git a/model/audio/device/soc/src/dsp.c b/model/audio/device/soc/src/dsp.c new file mode 100755 index 000000000..87ca7a7b0 --- /dev/null +++ b/model/audio/device/soc/src/dsp.c @@ -0,0 +1,483 @@ +/* + * Copyright (c) 2020-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_core.h" +#include "dsp_adapter.h" +#include "gpio_if.h" +#include "spi_if.h" +#include "tfa9879_codec.h" +#define DEFAULT_SPEED 2000000 +#define BITS_PER_WORD_EIGHT 8 +#define DSP_CS_NUM 1 +#define DSP_SPI_BUS_NUM 1 + +#define HDF_LOG_TAG dsp + +static int32_t DspLinkDeviceInit(const struct AudioCard *card, const struct DaiDevice *device); +static int32_t DspDeviceInit(const struct DspDevice *device); +static int32_t DspDeviceReadReg(struct DspDevice *device, uint8_t *buf, uint32_t len); +static int32_t DspDeviceWriteReg(struct DspDevice *device, uint8_t *buf, uint32_t len); +static int32_t DspLinkStartup(const struct AudioCard *card, const struct DaiDevice *device); +static int32_t DspLinkHwParams(const struct AudioCard *card, + const struct AudioPcmHwParams *param, const struct DaiDevice *device); +static int32_t DspDecodeAudioStream(struct AudioCard *card, void *buf, struct DspDevice *device); +static int32_t DspEncodeAudioStream(struct AudioCard *card, void *buf, struct DspDevice *device); +static int32_t DspEqualizerActive(struct AudioCard *card, void *buf, struct DspDevice *device); + +struct DspData g_dspData = { + .DspInit = DspDeviceInit, + .Read = DspDeviceReadReg, + .Write = DspDeviceWriteReg, + .decode = DspDecodeAudioStream, + .encode = DspEncodeAudioStream, + .Equalizer = DspEqualizerActive, +}; + +struct AudioDaiOps g_dspLinkDeviceOps = { + .Startup = DspLinkStartup, + .HwParams = DspLinkHwParams, +}; + +struct DaiData g_dspDaiData = { + .DaiInit = DspLinkDeviceInit, + .ops = &g_dspLinkDeviceOps, +}; + +struct SpiDevInfo g_devInfo = { + .busNum = DSP_SPI_BUS_NUM, + .csNum = DSP_CS_NUM, +}; + +static int32_t DspLinkStartup(const struct AudioCard *card, const struct DaiDevice *device) +{ + (void)card; + (void)device; + return HDF_SUCCESS; +} + +static int32_t DspCfgI2sFrequency(uint32_t rate, uint16_t *frequency) +{ + switch (rate) { + case I2S_SAMPLE_FREQUENCY_8000: + *frequency = I2S_SAMPLE_FREQUENCY_REG_VAL_8000; + break; + case I2S_SAMPLE_FREQUENCY_11025: + *frequency = I2S_SAMPLE_FREQUENCY_REG_VAL_11025; + break; + case I2S_SAMPLE_FREQUENCY_12000: + *frequency = I2S_SAMPLE_FREQUENCY_REG_VAL_12000; + break; + case I2S_SAMPLE_FREQUENCY_16000: + *frequency = I2S_SAMPLE_FREQUENCY_REG_VAL_16000; + break; + case I2S_SAMPLE_FREQUENCY_22050: + *frequency = I2S_SAMPLE_FREQUENCY_REG_VAL_22050; + break; + case I2S_SAMPLE_FREQUENCY_24000: + *frequency = I2S_SAMPLE_FREQUENCY_REG_VAL_24000; + break; + case I2S_SAMPLE_FREQUENCY_32000: + *frequency = I2S_SAMPLE_FREQUENCY_REG_VAL_32000; + break; + case I2S_SAMPLE_FREQUENCY_44100: + *frequency = I2S_SAMPLE_FREQUENCY_REG_VAL_44100; + break; + case I2S_SAMPLE_FREQUENCY_48000: + *frequency = I2S_SAMPLE_FREQUENCY_REG_VAL_48000; + break; + case I2S_SAMPLE_FREQUENCY_64000: + *frequency = I2S_SAMPLE_FREQUENCY_REG_VAL_64000; + break; + case I2S_SAMPLE_FREQUENCY_88200: + *frequency = I2S_SAMPLE_FREQUENCY_REG_VAL_88200; + break; + case I2S_SAMPLE_FREQUENCY_96000: + *frequency = I2S_SAMPLE_FREQUENCY_REG_VAL_96000; + break; + default: + AUDIO_DRIVER_LOG_ERR("rate: %d is not support.", rate); + return HDF_ERR_NOT_SUPPORT; + } + return HDF_SUCCESS; +} + +static int32_t DspSetI2sBitWidth(enum AudioFormat format, uint16_t *bitWidth) +{ + switch (format) { + case AUDIO_FORMAT_PCM_8_BIT: + *bitWidth = I2S_SAMPLE_FORMAT_REG_VAL_24; + break; + case AUDIO_FORMAT_PCM_16_BIT: + *bitWidth = I2S_SAMPLE_FORMAT_REG_VAL_24; + break; + case AUDIO_FORMAT_PCM_24_BIT: + *bitWidth = I2S_SAMPLE_FORMAT_REG_VAL_24; + break; + default: + AUDIO_DRIVER_LOG_ERR("format: %d is not support.", format); + return HDF_ERR_NOT_SUPPORT; + } + return HDF_SUCCESS; +} + +static int DspSetI2sFrequency(uint16_t frequencyVal) +{ + return HDF_SUCCESS; +} + +static int DspSetI2sFormat(uint16_t formatVal) +{ + return HDF_SUCCESS; +} + +static int32_t DspLinkHwParams(const struct AudioCard *card, + const struct AudioPcmHwParams *param, const struct DaiDevice *device) +{ + int ret; + uint16_t frequency, bitWidth; + (void)card; + (void)device; + AUDIO_DRIVER_LOG_DEBUG("entry."); + if (param == NULL || param->cardServiceName == NULL) { + AUDIO_DRIVER_LOG_ERR("input para is nullptr."); + return HDF_ERR_INVALID_PARAM; + } + ret = DspCfgI2sFrequency(param->rate, &frequency); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("RateToFrequency fail."); + return HDF_ERR_NOT_SUPPORT; + } + ret = DspSetI2sBitWidth(param->format, &bitWidth); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("FormatToBitWidth fail."); + return HDF_ERR_NOT_SUPPORT; + } + ret = DspSetI2sFrequency(frequency); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("SetDspI2sFs fail."); + return HDF_FAILURE; + } + ret = DspSetI2sFormat(bitWidth); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("SetDspI2sFormat fail."); + return HDF_FAILURE; + } + AUDIO_DRIVER_LOG_DEBUG("DspLinkHwParams: channels = %d, rate = %d, periodSize = %d, \ + periodCount = %d, format = %d, cardServiceName = %s \n", + param->channels, param->rate, param->periodSize, + param->periodCount, (uint32_t)param->format, param->cardServiceName); + AUDIO_DRIVER_LOG_DEBUG("success."); + return HDF_SUCCESS; +} + +static int DspPowerEnable(void) +{ + return HDF_SUCCESS; +} + +static int DspGpioPinInit(void) +{ + return HDF_SUCCESS; +} + +static int DspI2cPinInit(void) +{ + return HDF_SUCCESS; +} + +static int DspI2sInit(void) +{ + return HDF_SUCCESS; +} + +static int DspI2cInit(void) +{ + return HDF_SUCCESS; +} + +/* not init dsp gpio */ +static int DspSpiPinInit(void) +{ + return HDF_FAILURE; +} + +static int32_t DspDeviceInit(const struct DspDevice *device) +{ + DevHandle devHandle; + struct SpiCfg devCfg = { + .maxSpeedHz = DEFAULT_SPEED, + .mode = SPI_CLK_POLARITY, + .transferMode = SPI_DMA_TRANSFER, + .bitsPerWord = BITS_PER_WORD_EIGHT, + }; + + if (DspPowerEnable() != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("DspPowerEnable: return Error!"); + return HDF_FAILURE; + } + + if (DspGpioPinInit() != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("DspGpioPinInit: return Error!"); + return HDF_FAILURE; + } + + if (DspI2cPinInit() != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("DspI2cPinInit: return Error!"); + return HDF_FAILURE; + } + + if (DspSpiPinInit() == HDF_SUCCESS) { + devHandle = SpiOpen(&g_devInfo); + if (devHandle == NULL) { + AUDIO_DRIVER_LOG_ERR("DspDeviceOpen: Spi failed!"); + return HDF_FAILURE; + } + + if (SpiSetCfg(devHandle, &devCfg) != HDF_SUCCESS) { + SpiClose(devHandle); + AUDIO_DRIVER_LOG_ERR("DspDeviceCfg: spi failed!"); + return HDF_FAILURE; + } + SpiClose(devHandle); + } else { + AUDIO_DRIVER_LOG_ERR("Dsp Gpio Pin: not init!"); + } + + if (DspI2cInit() != HDF_SUCCESS) { + return HDF_FAILURE; + } + + if (DspI2sInit() != HDF_SUCCESS) { + return HDF_FAILURE; + } + + return HDF_SUCCESS; +} + +static int32_t DspDeviceReadReg(struct DspDevice *device, uint8_t *buf, uint32_t len) +{ + int32_t ret; + + DevHandle devHandle = SpiOpen(&g_devInfo); + if (devHandle == NULL) { + AUDIO_DRIVER_LOG_ERR("DspDeviceOpen: Spi failed!"); + return HDF_FAILURE; + } + + ret = SpiRead(devHandle, buf, len); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("DspDeviceRead: spi failed!"); + SpiClose(devHandle); + return HDF_FAILURE; + } + + SpiClose(devHandle); + + return HDF_SUCCESS; +} + +static int32_t DspDeviceWriteReg(struct DspDevice *device, uint8_t *buf, uint32_t len) +{ + int32_t ret; + + DevHandle devHandle = SpiOpen(&g_devInfo); + if (devHandle == NULL) { + AUDIO_DRIVER_LOG_ERR("DspDeviceOpen: Spi failed!"); + return HDF_FAILURE; + } + + ret = SpiWrite(devHandle, buf, len); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("DspDeviceRead: spi failed!"); + SpiClose(devHandle); + return HDF_FAILURE; + } + + SpiClose(devHandle); + + return HDF_SUCCESS; +} + +static int32_t DspLinkDeviceInit(const struct AudioCard *card, const struct DaiDevice *device) +{ + if (device == NULL || device->devDaiName == NULL) { + AUDIO_DRIVER_LOG_ERR("input para is nullptr."); + return HDF_FAILURE; + } + AUDIO_DRIVER_LOG_DEBUG("dsp Link device name: %s\n", device->devDaiName); + (void)card; + return HDF_SUCCESS; +} + +static int32_t DspDriverBind(struct HdfDeviceObject *device) +{ + struct AudioHost *audioHost = NULL; + + AUDIO_DRIVER_LOG_DEBUG("entry."); + if (device == NULL) { + AUDIO_DRIVER_LOG_ERR("device is NULL."); + return HDF_ERR_INVALID_OBJECT; + } + + audioHost = AudioHostCreateAndBind(device); + if (audioHost == NULL) { + AUDIO_DRIVER_LOG_ERR("audioHost create failed!"); + return HDF_FAILURE; + } + + AUDIO_DRIVER_LOG_DEBUG("dsp band success."); + return HDF_SUCCESS; +} + +static int32_t DspGetServiceName(const struct HdfDeviceObject *device, const char **drvDspName) +{ + const struct DeviceResourceNode *node = NULL; + struct DeviceResourceIface *drsOps = NULL; + int32_t ret; + + if (device == NULL) { + AUDIO_DRIVER_LOG_ERR("device is NULL."); + return HDF_FAILURE; + } + + node = device->property; + if (node == NULL) { + AUDIO_DRIVER_LOG_ERR("deivce property is NULL."); + return HDF_FAILURE; + } + drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); + if (drsOps == NULL || drsOps->GetString == NULL) { + AUDIO_DRIVER_LOG_ERR("from resource get drsops failed!"); + return HDF_FAILURE; + } + + ret = drsOps->GetString(node, "serviceName", drvDspName, 0); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("read DspServiceName fail!"); + return ret; + } + + return HDF_SUCCESS; +} + +static int32_t DspGetDaiName(const struct HdfDeviceObject *device, const char **drvDaiName) +{ + const struct DeviceResourceNode *node = NULL; + struct DeviceResourceIface *drsOps = NULL; + int32_t ret; + + if (device == NULL) { + AUDIO_DRIVER_LOG_ERR("input para is null pointer."); + return HDF_FAILURE; + } + + node = device->property; + if (node == NULL) { + AUDIO_DRIVER_LOG_ERR("drs node is null pointer."); + return HDF_FAILURE; + } + drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); + if (drsOps == NULL || drsOps->GetString == NULL) { + AUDIO_DRIVER_LOG_ERR("drs ops fail!"); + return HDF_FAILURE; + } + + ret = drsOps->GetString(node, "dspDaiName", drvDaiName, 0); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("read dspDaiName fail!"); + return ret; + } + + return HDF_SUCCESS; +} + +static int32_t DspDriverInit(struct HdfDeviceObject *device) +{ + int32_t ret; + AUDIO_DRIVER_LOG_DEBUG("entry.\n"); + if (device == NULL) { + AUDIO_DRIVER_LOG_ERR("device is NULL."); + return HDF_ERR_INVALID_OBJECT; + } + + ret = DspGetServiceName(device, &g_dspData.drvDspName); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("get dsp service name fail."); + return ret; + } + + ret = DspGetDaiName(device, &g_dspDaiData.drvDaiName); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("get dsp dai name fail."); + return ret; + } + + ret = AudioRegisterDeviceDsp(device, &g_dspData, &g_dspDaiData); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("register dai fail."); + return ret; + } + AUDIO_DRIVER_LOG_DEBUG("Success!\n"); + return HDF_SUCCESS; +} + + +static void DspDriverRelease(struct HdfDeviceObject *device) +{ + struct DspHost *dspHost = NULL; + if (device == NULL) { + AUDIO_DRIVER_LOG_ERR("device is NULL"); + return; + } + + dspHost = (struct DspHost *)device->service; + if (dspHost == NULL) { + AUDIO_DRIVER_LOG_ERR("DspHost is NULL"); + return; + } + + OsalIoUnmap((void *)((uintptr_t)(void*)&dspHost->priv)); + OsalMemFree(dspHost); +} + +static int32_t DspEqualizerActive(struct AudioCard *card, void *buf, struct DspDevice *device) +{ + (void)card; + (void)buf; + (void)device; + AUDIO_DRIVER_LOG_DEBUG("equalizer run!!!"); + return HDF_SUCCESS; +} + +static int32_t DspDecodeAudioStream(struct AudioCard *card, void *buf, struct DspDevice *device) +{ + (void)card; + (void)buf; + (void)device; + AUDIO_DRIVER_LOG_DEBUG("decode run!!!"); + return HDF_SUCCESS; +} + +static int32_t DspEncodeAudioStream(struct AudioCard *card, void *buf, struct DspDevice *device) +{ + (void)card; + (void)buf; + (void)device; + AUDIO_DRIVER_LOG_DEBUG("encode run!!!"); + return HDF_SUCCESS; +} + +/* HdfDriverEntry definitions */ +struct HdfDriverEntry g_dspDriverEntry = { + .moduleVersion = 1, + .moduleName = "DSP", + .Bind = DspDriverBind, + .Init = DspDriverInit, + .Release = DspDriverRelease, +}; +HDF_INIT(g_dspDriverEntry); diff --git a/model/audio/device/soc/src/platform.c b/model/audio/device/soc/src/platform.c new file mode 100755 index 000000000..34ebb449a --- /dev/null +++ b/model/audio/device/soc/src/platform.c @@ -0,0 +1,1170 @@ +/* + * Copyright (c) 2020-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 "gpio_if.h" +#include +#include "audio_core.h" +#include +#include "hi3516_aiao.h" +#include "hi3516_codec.h" +#include "osal_io.h" +#include "osal_mem.h" + +#define HDF_LOG_TAG platform +const int AIAO_BUFF_OFFSET = 128; +const int AIAO_BUFF_POINT = 320; +const int AIAO_BUFF_TRANS = 16 * 1024; +const int AIAO_BUFF_SIZE = 128 * 1024; +const int RENDER_TRAF_BUF_SIZE = 1024; +const int CAPTURE_TRAF_BUF_SIZE = 1024 * 16; + +const int AUDIO_BUFF_MIN = 128; +const int AUDIO_RECORD_MIN = 1024 * 16; +const int BITSTOBYTE = 8; + +static int g_captureBuffFreeCount = 0; +static int g_captureBuffInitCount = 0; +static int g_renderBuffFreeCount = 0; +static int g_renderBuffInitCount = 0; + +const int MIN_PERIOD_SIZE = 4096; +const int MAX_PERIOD_SIZE = 1024 * 16; +const int MIN_PERIOD_COUNT = 8; +const int MAX_PERIOD_COUNT = 32; +const int MAX_AIAO_BUFF_SIZE = 128 * 1024; +const int MIN_AIAO_BUFF_SIZE = 16 * 1024; + +/* HdfDriverEntry implementations */ +static int32_t PlatformDriverBind(struct HdfDeviceObject *device) +{ + struct PlatformHost *platformHost = NULL; + AUDIO_DRIVER_LOG_DEBUG("entry!"); + + if (device == NULL) { + AUDIO_DRIVER_LOG_ERR("input para is NULL."); + return HDF_FAILURE; + } + + platformHost = (struct PlatformHost *)OsalMemCalloc(sizeof(*platformHost)); + if (platformHost == NULL) { + AUDIO_DRIVER_LOG_ERR("malloc host fail!"); + return HDF_FAILURE; + } + + platformHost->device = device; + platformHost->platformInitFlag = false; + device->service = &platformHost->service; + + AUDIO_DRIVER_LOG_DEBUG("success!"); + return HDF_SUCCESS; +} + +int32_t AudioRenderBuffInit(struct PlatformHost *platformHost) +{ + unsigned int buffSize; + if (platformHost == NULL) { + AUDIO_DRIVER_LOG_ERR("input para is NULL."); + return HDF_FAILURE; + } + + if (platformHost->renderBufInfo.virtAddr != NULL) { + return HDF_SUCCESS; + } + + buffSize = platformHost->renderBufInfo.periodCount * platformHost->renderBufInfo.periodSize; + if (buffSize < MIN_AIAO_BUFF_SIZE || buffSize > MAX_AIAO_BUFF_SIZE) { + AUDIO_DRIVER_LOG_ERR("buffSize is invalid."); + return HDF_FAILURE; + } + AUDIO_DRIVER_LOG_INFO("buffSize = %d ", buffSize); + + platformHost->renderBufInfo.phyAddr = 0; + platformHost->renderBufInfo.virtAddr = dma_alloc_writecombine(NULL, buffSize, + (dma_addr_t *)&platformHost->renderBufInfo.phyAddr, GFP_DMA | GFP_KERNEL); + + if (platformHost->renderBufInfo.virtAddr == NULL) { + AUDIO_DRIVER_LOG_ERR("mem alloc failed."); + return HDF_FAILURE; + } + platformHost->renderBufInfo.cirBufSize = buffSize; + + AUDIO_DRIVER_LOG_DEBUG("phyAddr = %x virtAddr = %x", + platformHost->renderBufInfo.phyAddr, platformHost->renderBufInfo.virtAddr); + AUDIO_DRIVER_LOG_DEBUG("g_renderBuffInitCount: %d", g_renderBuffInitCount++); + + return HDF_SUCCESS; +} + +int32_t AudioRenderBuffFree(struct PlatformHost *platformHost) +{ + if (platformHost == NULL) { + AUDIO_DRIVER_LOG_ERR("input para is NULL."); + return HDF_FAILURE; + } + + if (platformHost->renderBufInfo.virtAddr != NULL) { + dma_free_writecombine(NULL, platformHost->renderBufInfo.cirBufSize, platformHost->renderBufInfo.virtAddr, + platformHost->renderBufInfo.phyAddr); + } + + AUDIO_DRIVER_LOG_DEBUG("g_renderBuffFreeCount: %d", g_renderBuffFreeCount++); + + platformHost->renderBufInfo.virtAddr = NULL; + platformHost->renderBufInfo.phyAddr = 0; + return HDF_SUCCESS; +} + +int32_t AudioCaptureBuffInit(struct PlatformHost *platformHost) +{ + unsigned int buffSize; + if (platformHost == NULL) { + AUDIO_DRIVER_LOG_ERR("input para is NULL."); + return HDF_FAILURE; + } + if (platformHost->captureBufInfo.virtAddr != NULL) { + return HDF_SUCCESS; + } + buffSize = platformHost->captureBufInfo.periodCount * platformHost->captureBufInfo.periodSize; + if (buffSize < MIN_AIAO_BUFF_SIZE || buffSize > MAX_AIAO_BUFF_SIZE) { + AUDIO_DRIVER_LOG_ERR("buffSize is invalid."); + return HDF_FAILURE; + } + AUDIO_DRIVER_LOG_INFO("buffSize = %d ", buffSize); + + platformHost->captureBufInfo.phyAddr = 0; + platformHost->captureBufInfo.virtAddr = dma_alloc_writecombine(NULL, buffSize, + (dma_addr_t *)&platformHost->captureBufInfo.phyAddr, GFP_DMA | GFP_KERNEL); + + if (platformHost->captureBufInfo.virtAddr == NULL) { + AUDIO_DRIVER_LOG_ERR("mem alloc failed."); + return HDF_FAILURE; + } + platformHost->captureBufInfo.cirBufSize = buffSize; + + AUDIO_DRIVER_LOG_DEBUG("phyAddr = %x virtAddr = %x", + platformHost->captureBufInfo.phyAddr, platformHost->captureBufInfo.virtAddr); + AUDIO_DRIVER_LOG_DEBUG("g_captureBuffInitCount: %d", g_captureBuffInitCount++); + + return HDF_SUCCESS; +} + +int32_t AudioCaptureBuffFree(struct PlatformHost *platformHost) +{ + if (platformHost == NULL) { + AUDIO_DRIVER_LOG_ERR("input para is NULL."); + return HDF_FAILURE; + } + + if (platformHost->captureBufInfo.virtAddr != NULL) { + dma_free_writecombine(NULL, platformHost->captureBufInfo.cirBufSize, platformHost->captureBufInfo.virtAddr, + platformHost->captureBufInfo.phyAddr); + } + AUDIO_DRIVER_LOG_DEBUG("g_captureBuffFreeCount: %d", g_captureBuffFreeCount++); + + platformHost->captureBufInfo.virtAddr = NULL; + platformHost->captureBufInfo.phyAddr = 0; + return HDF_SUCCESS; +} + +int32_t AudioAoInit(const struct PlatformHost *platformHost) +{ + int ret; + + if (platformHost == NULL) { + AUDIO_DRIVER_LOG_ERR("input para is NULL."); + return HDF_FAILURE; + } + + if (platformHost->renderBufInfo.phyAddr == 0) { + AUDIO_DRIVER_LOG_ERR("phyAddr is error"); + return HDF_FAILURE; + } + ret = AopHalSetBufferAddr(0, platformHost->renderBufInfo.phyAddr); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("failed."); + return HDF_FAILURE; + } + + ret = AopHalSetBufferSize(0, platformHost->renderBufInfo.cirBufSize); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("AopHalSetBufferSize: failed."); + return HDF_FAILURE; + } + + AUDIO_DRIVER_LOG_DEBUG("AopHalSetBufferSize: %d", platformHost->renderBufInfo.cirBufSize); + + ret = AopHalSetTransSize(0, platformHost->renderBufInfo.trafBufSize); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("aop_hal_set_trans_size: faile."); + return HDF_FAILURE; + } + + return HDF_SUCCESS; +} + +int32_t AudioAiInit(const struct PlatformHost *platformHost) +{ + int ret; + if (platformHost == NULL) { + AUDIO_DRIVER_LOG_ERR("input para is NULL."); + return HDF_FAILURE; + } + + if (platformHost->captureBufInfo.phyAddr == 0) { + AUDIO_DRIVER_LOG_ERR("phyAddr is error"); + return HDF_FAILURE; + } + + ret = AipHalSetBufferAddr(0, platformHost->captureBufInfo.phyAddr); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("AipHalSetBufferAddr: failed."); + return HDF_FAILURE; + } + + ret = AipHalSetBufferSize(0, platformHost->captureBufInfo.cirBufSize); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("AipHalSetBufferSize: failed."); + return HDF_FAILURE; + } + + ret = AipHalSetTransSize(0, AIAO_BUFF_POINT); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("AipHalSetTransSize: faile."); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +static void SysWritelI2s(unsigned long addr, unsigned int value) +{ + *(volatile unsigned int *)(addr) = value; +} + +int32_t AiaoSysPinMux(void) +{ + static void *regIocfg2Base = 0; + static void *regIocfg3Base = 0; + static void *regGpioBase = 0; + + regIocfg2Base = OsalIoRemap(IOCFG2_BASE_ADDR, BASE_ADDR_REMAP_SIZE); + if (regIocfg2Base == NULL) { + AUDIO_DRIVER_LOG_ERR("regIocfg2Base is NULL."); + return HDF_FAILURE; + } + + regIocfg3Base = OsalIoRemap(IOCFG3_BASE_ADDR, BASE_ADDR_REMAP_SIZE); + if (regIocfg3Base == NULL) { + AUDIO_DRIVER_LOG_ERR("g_regIocfg3Base is NULL."); + return HDF_FAILURE; + } + + regGpioBase = OsalIoRemap(GPIO_BASE_ADDR, BASE_ADDR_REMAP_SIZE); + if (regGpioBase == NULL) { + AUDIO_DRIVER_LOG_ERR("g_regGpioBase is NULL."); + return HDF_FAILURE; + } + + AUDIO_DRIVER_LOG_DEBUG("I2s0PinMuxAmpUnmute i2s0_pin_mux"); + SysWritelI2s((uintptr_t)regIocfg2Base + I2S_IOCFG2_BASE1, I2S_IOCFG2_BASE1_VAL); + SysWritelI2s((uintptr_t)regIocfg2Base + I2S_IOCFG2_BASE2, I2S_IOCFG2_BASE2_VAL); + SysWritelI2s((uintptr_t)regIocfg2Base + I2S_IOCFG2_BASE3, I2S_IOCFG2_BASE3_VAL); + SysWritelI2s((uintptr_t)regIocfg2Base + I2S_IOCFG2_BASE4, I2S_IOCFG2_BASE4_VAL); + SysWritelI2s((uintptr_t)regIocfg2Base + I2S_IOCFG2_BASE5, I2S_IOCFG2_BASE5_VAL); + + AUDIO_DRIVER_LOG_DEBUG("I2s0PinMuxAmpUnmute AmpUnmute"); + SysWritelI2s((uintptr_t)regIocfg3Base + I2S_IOCFG3_BASE1, I2S_IOCFG3_BASE1_VAL); + SysWritelI2s((uintptr_t)regGpioBase + GPIO_BASE1, GPIO_BASE3_VAL); + SysWritelI2s((uintptr_t)regGpioBase + GPIO_BASE2, GPIO_BASE2_VAL); + SysWritelI2s((uintptr_t)regGpioBase + GPIO_BASE3, GPIO_BASE3_VAL); + + return HDF_SUCCESS; +} + + +int32_t AudioPlatformDeviceInit(const struct AudioCard *card, const struct PlatformDevice *platform) +{ + struct PlatformHost *platformHost = NULL; + int ret; + unsigned int chnId = 0; + + if (platform == NULL || platform->device == NULL) { + AUDIO_DRIVER_LOG_ERR("platform is NULL."); + return HDF_FAILURE; + } + (void)card; + + platformHost = (struct PlatformHost *)platform->device->service; + if (platformHost == NULL) { + AUDIO_DRIVER_LOG_ERR("platform host is NULL."); + return HDF_FAILURE; + } + + if (platformHost->platformInitFlag == true) { + AUDIO_DRIVER_LOG_DEBUG("platform init complete!"); + return HDF_SUCCESS; + } + platformHost->platformInitFlag = true; + + ret = AiaoHalSysInit(); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("AiaoHalSysInit: faile."); + return HDF_FAILURE; + } + + /* PIN MUX */ + ret = AiaoSysPinMux(); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("AiaoSysPinMux fail."); + return HDF_FAILURE; + } + + /* CLK reset */ + ret = AiaoClockReset(); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("AiaoClockReset: faile."); + return HDF_FAILURE; + } + + /* aiao init */ + ret = AiaoDeviceInit(chnId); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("AiaoClockReset: faile."); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +int32_t RenderSetAiaoAttr(struct PlatformHost *platformHost, const struct AudioPcmHwParams *param) +{ + if (platformHost == NULL || param == NULL) { + AUDIO_DRIVER_LOG_ERR("platform is NULL."); + return HDF_FAILURE; + } + platformHost->renderBufInfo.period = param->period; + if (param->periodSize < MIN_PERIOD_SIZE || param->periodSize > MAX_PERIOD_SIZE) { + AUDIO_DRIVER_LOG_ERR("periodSize is invalid."); + return HDF_FAILURE; + } + platformHost->renderBufInfo.periodSize = param->periodSize; + if (param->periodCount < MIN_PERIOD_COUNT || param->periodCount > MAX_PERIOD_COUNT) { + AUDIO_DRIVER_LOG_ERR("periodCount is invalid."); + return HDF_FAILURE; + } + platformHost->renderBufInfo.periodCount = param->periodCount; + + platformHost->renderBufInfo.trafBufSize = RENDER_TRAF_BUF_SIZE; + return HDF_SUCCESS; +} + +int32_t CaptureSetAiaoAttr(struct PlatformHost *platformHost, const struct AudioPcmHwParams *param) +{ + if (platformHost == NULL || param == NULL) { + AUDIO_DRIVER_LOG_ERR("platform is NULL."); + return HDF_FAILURE; + } + + platformHost->captureBufInfo.period = param->period; + if (param->periodSize < MIN_PERIOD_SIZE || param->periodSize > MAX_PERIOD_SIZE) { + AUDIO_DRIVER_LOG_ERR("periodSize is invalid %d.", param->periodSize); + return HDF_FAILURE; + } + platformHost->captureBufInfo.periodSize = param->periodSize; + if (param->periodCount < MIN_PERIOD_COUNT || param->periodCount > MAX_PERIOD_COUNT) { + AUDIO_DRIVER_LOG_ERR("periodCount is invalid %d.", param->periodCount); + return HDF_FAILURE; + } + platformHost->captureBufInfo.periodCount = param->periodCount; + + if (param->silenceThreshold < MIN_PERIOD_SIZE || param->silenceThreshold > MAX_PERIOD_SIZE) { + AUDIO_DRIVER_LOG_ERR("silenceThreshold is invalid %d.", param->silenceThreshold); + platformHost->captureBufInfo.trafBufSize = CAPTURE_TRAF_BUF_SIZE; + } else { + platformHost->captureBufInfo.trafBufSize = param->silenceThreshold; + } + return HDF_SUCCESS; +} + +int32_t PlatformHwParams(const struct AudioCard *card, const struct AudioPcmHwParams *param) +{ + int ret; + const int chnlCntMin = 1; + const int chnlCntMax = 2; + struct PlatformHost *platformHost = NULL; + AUDIO_DRIVER_LOG_DEBUG("entry."); + + if (card == NULL || card->rtd == NULL || card->rtd->platform == NULL || + param == NULL || param->cardServiceName == NULL) { + AUDIO_DRIVER_LOG_ERR("input para is NULL."); + return HDF_FAILURE; + } + + if (param->channels < chnlCntMin || param->channels > chnlCntMax) { + AUDIO_DRIVER_LOG_ERR("channels para is invalid."); + return HDF_FAILURE; + } + + platformHost = PlatformHostFromDevice(card->rtd->platform->device); + if (platformHost == NULL) { + AUDIO_DRIVER_LOG_ERR("platformHost is null."); + return HDF_FAILURE; + } + + platformHost->pcmInfo.rate = param->rate; + platformHost->pcmInfo.frameSize = param->channels * platformHost->pcmInfo.bitWidth / BITSTOBYTE; + + platformHost->renderBufInfo.chnId = 0; + platformHost->captureBufInfo.chnId = 0; + + platformHost->pcmInfo.isBigEndian = param->isBigEndian; + platformHost->pcmInfo.isSignedData = param->isSignedData; + + platformHost->pcmInfo.startThreshold = param->startThreshold; + platformHost->pcmInfo.stopThreshold = param->stopThreshold; + platformHost->pcmInfo.silenceThreshold = param->silenceThreshold; + + if (param->streamType == AUDIO_RENDER_STREAM) { + ret = RenderSetAiaoAttr(platformHost, param); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("AoSetClkAttr: fail."); + return HDF_FAILURE; + } + } else if (param->streamType == AUDIO_CAPTURE_STREAM) { + ret = CaptureSetAiaoAttr(platformHost, param); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("AiSetClkAttr: fail."); + return HDF_FAILURE; + } + } else { + AUDIO_DRIVER_LOG_ERR("param streamType is invalid."); + return HDF_FAILURE; + } + AUDIO_DRIVER_LOG_DEBUG("success."); + return HDF_SUCCESS; +} + +int32_t PlatformCreatePlatformHost(const struct AudioCard *card, struct PlatformHost **platformHost) +{ + if (platformHost == NULL) { + AUDIO_DRIVER_LOG_ERR("input param platformHost is invalid."); + return HDF_ERR_INVALID_PARAM; + } + if (card == NULL || card->rtd == NULL || card->rtd->platform == NULL) { + AUDIO_DRIVER_LOG_ERR("input para is NULL."); + return HDF_FAILURE; + } + + *platformHost = PlatformHostFromDevice(card->rtd->platform->device); + if (*platformHost == NULL) { + AUDIO_DRIVER_LOG_ERR("PlatformHostFromDevice faile."); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +int32_t PlatformRenderPrepare(const struct AudioCard *card) +{ + int ret; + struct PlatformHost *platformHost = NULL; + AUDIO_DRIVER_LOG_DEBUG("PlatformPrepare: entry."); + + ret = PlatformCreatePlatformHost(card, &platformHost); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("PlatformCreatePlatformHost failed."); + return HDF_FAILURE; + } + + if (platformHost->renderBufInfo.virtAddr == NULL) { + ret = AudioRenderBuffInit(platformHost); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("AudioRenderBuffInit: fail."); + return HDF_FAILURE; + } + + ret = AudioAoInit(platformHost); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("AudioAoInit: fail."); + return HDF_FAILURE; + } + } + + (void)memset_s(platformHost->renderBufInfo.virtAddr, + platformHost->renderBufInfo.cirBufSize, 0, + platformHost->renderBufInfo.cirBufSize); + platformHost->renderBufInfo.wbufOffSet = 0; + platformHost->renderBufInfo.wptrOffSet = 0; + platformHost->pcmInfo.totalStreamSize = 0; + + ret = AopHalSetBuffWptr(0, 0); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("AopHalSetBuffWptr: failed."); + return HDF_FAILURE; + } + + ret = AopHalSetBuffRptr(0, 0); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("AopHalSetBuffRptr: failed."); + return HDF_FAILURE; + } + AUDIO_DRIVER_LOG_DEBUG("success."); + return HDF_SUCCESS; +} + +int32_t PlatformCapturePrepare(const struct AudioCard *card) +{ + int ret; + struct PlatformHost *platformHost = NULL; + AUDIO_DRIVER_LOG_DEBUG("entry."); + + ret = PlatformCreatePlatformHost(card, &platformHost); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("PlatformCreatePlatformHost failed."); + return HDF_FAILURE; + } + + if (platformHost->captureBufInfo.virtAddr == NULL) { + ret = AudioCaptureBuffInit(platformHost); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("AudioCaptureBuffInit: fail."); + return HDF_FAILURE; + } + ret = AudioAiInit(platformHost); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("AudioAiInit: fail."); + return HDF_FAILURE; + } + } + + (void)memset_s(platformHost->captureBufInfo.virtAddr, + platformHost->captureBufInfo.cirBufSize, 0, + platformHost->captureBufInfo.cirBufSize); + platformHost->captureBufInfo.wbufOffSet = 0; + platformHost->captureBufInfo.wptrOffSet = 0; + platformHost->captureBufInfo.chnId = 0; + platformHost->pcmInfo.totalStreamSize = 0; + + ret = AipHalSetBuffWptr(0, 0); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("AipHalSetBuffWptr: failed."); + return HDF_FAILURE; + } + + ret = AipHalSetBuffRptr(0, 0); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("AipHalSetBuffRptr: failed."); + return HDF_FAILURE; + } + + AUDIO_DRIVER_LOG_DEBUG("success."); + return HDF_SUCCESS; +} + +int32_t AudioDataBigEndianChange(char *srcData, uint32_t audioLen, enum AuidoBitWidth bitWidth) +{ + uint64_t i; + uint16_t framesize; + char temp; + if (srcData == NULL) { + AUDIO_DRIVER_LOG_ERR("srcData is NULL."); + return HDF_FAILURE; + } + + switch (bitWidth) { + case BIT_WIDTH8: + framesize = 1; /* 1 byte */ + break; + case BIT_WIDTH16: + framesize = 2; /* 2 bytes */ + break; + case BIT_WIDTH24: + framesize = 3; /* 3 bytes */ + break; + default: + framesize = 2; /* default 2 bytes */ + break; + } + + for (i = 0; i < audioLen; i += framesize) { + temp = srcData[i]; + srcData[i] = srcData[i + framesize - 1]; + srcData[i + framesize - 1] = temp; + } + AUDIO_DRIVER_LOG_DEBUG("audioLen = %d\n", audioLen); + return HDF_SUCCESS; +} + + +static int32_t UpdateWriteBufData(struct PlatformHost *platformHost, unsigned int wptr, + unsigned int buffSize, unsigned int *buffOffset, const char *buf) +{ + int ret; + unsigned int buffFirstSize; + unsigned int buffSecordSize; + if (platformHost == NULL || buffOffset == NULL || buf == NULL) { + AUDIO_DRIVER_LOG_ERR("input param is invalid."); + return HDF_ERR_INVALID_PARAM; + } + + if (platformHost->renderBufInfo.cirBufSize - wptr >= buffSize) { + *buffOffset = wptr + buffSize; + ret = memcpy_s((char *)(platformHost->renderBufInfo.virtAddr) + wptr, + buffSize, buf, buffSize); + if (ret != 0) { + AUDIO_DRIVER_LOG_ERR("memcpy_s failed."); + return HDF_FAILURE; + } + if (*buffOffset >= platformHost->renderBufInfo.cirBufSize) { + *buffOffset = 0; + } + } else { + buffFirstSize = platformHost->renderBufInfo.cirBufSize - wptr; + ret = memcpy_s((char *)(platformHost->renderBufInfo.virtAddr) + wptr, + buffFirstSize, buf, buffFirstSize); + if (ret != 0) { + AUDIO_DRIVER_LOG_ERR("memcpy_s failed."); + return HDF_FAILURE; + } + + buffSecordSize = buffSize - buffFirstSize; + ret = memcpy_s((char *)platformHost->renderBufInfo.virtAddr, + buffSecordSize, buf + buffFirstSize, + buffSecordSize); + if (ret != 0) { + AUDIO_DRIVER_LOG_ERR("memcpy_s failed."); + return HDF_FAILURE; + } + *buffOffset = buffSecordSize; + } + return HDF_SUCCESS; +} + +static int32_t UpdateWriteBuffOffset(struct PlatformHost *platformHost, + unsigned int buffSize, unsigned int *buffOffset, struct AudioTxData *txData) +{ + unsigned int buffAvailable; + int ret; + unsigned int wptr; + unsigned int rptr; + int devId; + if (platformHost == NULL || buffOffset == NULL || txData == NULL) { + AUDIO_DRIVER_LOG_ERR("input param is invalid."); + return HDF_ERR_INVALID_PARAM; + } + + devId = platformHost->renderBufInfo.chnId; + rptr = AiaoHalReadReg(AopBuffRptrReg(devId)); + wptr = AiaoHalReadReg(AopBuffWptrReg(devId)); + AUDIO_DRIVER_LOG_DEBUG("rptrReg = [0x%08x, wptrReg = [0x%08x], input size = [%u]", + rptr, wptr, buffSize); + + if (wptr >= rptr) { + // [S ... R ... W ... E] + buffAvailable = platformHost->renderBufInfo.cirBufSize - (wptr - rptr); + + if (buffAvailable < buffSize + AUDIO_BUFF_MIN) { + AUDIO_DRIVER_LOG_DEBUG("not available buffer."); + txData->status = ENUM_CIR_BUFF_FULL; + return HDF_SUCCESS; + } + + ret = UpdateWriteBufData(platformHost, wptr, buffSize, buffOffset, txData->buf); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("aop_hal_set_buff_wptr failed."); + return HDF_FAILURE; + } + } else { + // [S ... W ... R ... E] + buffAvailable = rptr - wptr; + + if (buffAvailable < buffSize + AUDIO_BUFF_MIN) { + AUDIO_DRIVER_LOG_DEBUG("not available buffer."); + txData->status = ENUM_CIR_BUFF_FULL; + return HDF_SUCCESS; + } + + *buffOffset = wptr + buffSize; + ret = memcpy_s((char *)(platformHost->renderBufInfo.virtAddr) + wptr, + buffSize, txData->buf, buffSize); + if (ret != 0) { + AUDIO_DRIVER_LOG_ERR("memcpy_s failed."); + return HDF_FAILURE; + } + } + return HDF_SUCCESS; +} + +static int32_t SetWriteBuffWptr(struct PlatformHost *platformHost, + unsigned int buffSize, struct AudioTxData *txData) +{ + int ret; + int devId; + int buffOffset; + + if (platformHost == NULL || txData == NULL) { + AUDIO_DRIVER_LOG_ERR("input param is invalid."); + return HDF_ERR_INVALID_PARAM; + } + + devId = platformHost->renderBufInfo.chnId; + ret = UpdateWriteBuffOffset(platformHost, buffSize, &buffOffset, txData); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("UpdateWptrRptr: failed."); + return HDF_FAILURE; + } + if (txData->status == ENUM_CIR_BUFF_FULL) { + AUDIO_DRIVER_LOG_DEBUG("not available buffer wait a minute."); + return HDF_SUCCESS; + } + + if (platformHost->renderBufInfo.runStatus == 1) { + platformHost->pcmInfo.totalStreamSize += buffSize; + ret = AopHalSetBuffWptr(devId, buffOffset); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("AopHalSetBuffWptr failed."); + return HDF_FAILURE; + } + } + txData->status = ENUM_CIR_BUFF_NORMAL; + return HDF_SUCCESS; +} + +int32_t PlatformWrite(const struct AudioCard *card, struct AudioTxData *txData) +{ + int buffSize; + + unsigned int startThreshold; + struct PlatformHost *platformHost = NULL; + AUDIO_DRIVER_LOG_DEBUG("entry."); + + if (card == NULL || card->rtd == NULL || card->rtd->platform == NULL || + txData == NULL || txData->buf == NULL) { + AUDIO_DRIVER_LOG_ERR("param is null."); + return HDF_FAILURE; + } + + platformHost = PlatformHostFromDevice(card->rtd->platform->device); + if (platformHost == NULL) { + AUDIO_DRIVER_LOG_ERR("PlatformHostFromDevice is invalid."); + return HDF_FAILURE; + } + + OsalMutexLock(&platformHost->renderBufInfo.buffMutex); + if (platformHost->renderBufInfo.virtAddr == NULL) { + AUDIO_DRIVER_LOG_ERR("renderBufInfo.virtAddr is nullptr."); + OsalMutexUnlock(&platformHost->renderBufInfo.buffMutex); + return HDF_FAILURE; + } + buffSize = txData->frames * platformHost->pcmInfo.frameSize; + startThreshold = platformHost->pcmInfo.startThreshold * platformHost->pcmInfo.frameSize; + + if (buffSize >= platformHost->renderBufInfo.cirBufSize) { + AUDIO_DRIVER_LOG_ERR("stream data too long."); + OsalMutexUnlock(&platformHost->renderBufInfo.buffMutex); + return HDF_FAILURE; + } + + if (platformHost->pcmInfo.isBigEndian) { + if (AudioDataBigEndianChange(txData->buf, buffSize, platformHost->pcmInfo.bitWidth) != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("AudioDataBigEndianChange: failed."); + OsalMutexUnlock(&platformHost->renderBufInfo.buffMutex); + return HDF_FAILURE; + } + } + + if (platformHost->renderBufInfo.runStatus == 1) { + if ((platformHost->renderBufInfo.enable == 0) && + (platformHost->pcmInfo.totalStreamSize > startThreshold)) { + AopHalDevEnable(platformHost->captureBufInfo.chnId); + platformHost->renderBufInfo.enable = 1; + } + } + + if (SetWriteBuffWptr(platformHost, buffSize, txData) != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("SetWriteBuffWptr: failed."); + OsalMutexUnlock(&platformHost->renderBufInfo.buffMutex); + return HDF_FAILURE; + } + OsalMutexUnlock(&platformHost->renderBufInfo.buffMutex); + + AUDIO_DRIVER_LOG_DEBUG("now total = %d", platformHost->pcmInfo.totalStreamSize); + return HDF_SUCCESS; +} + +static int32_t UpdateReadBuffData(const struct PlatformHost *platformHost, + unsigned int *tranferSize, unsigned int *buffOffset, + struct AudioRxData *rxData) +{ + unsigned int dataAvailable; + unsigned int validData; + unsigned int wptr; + unsigned int rptr; + int devId; + devId = platformHost->captureBufInfo.chnId; + // Buf/DMA offset + rptr = AiaoHalReadReg(AipBuffRptrReg(devId)); + wptr = AiaoHalReadReg(AipBuffWptrReg(devId)); + // Buf manage + if (wptr >= rptr) { + // [S ... R ... W ... E] + dataAvailable = wptr - rptr; + + if (dataAvailable >= platformHost->captureBufInfo.trafBufSize) { + rxData->buf = (char *)(platformHost->captureBufInfo.virtAddr) + rptr; + *tranferSize = platformHost->captureBufInfo.trafBufSize; + *buffOffset = rptr + *tranferSize; + } else { + AUDIO_DRIVER_LOG_DEBUG("PlatformRead: not available data."); + rxData->buf = (char *)(platformHost->captureBufInfo.virtAddr) + rptr; + rxData->status = ENUM_CIR_BUFF_EMPTY; + rxData->bufSize = 0; + rxData->frames = 0; + return HDF_SUCCESS; + } + + AUDIO_DRIVER_LOG_DEBUG("tranferSize : %d buffOffset : %d ", *tranferSize, *buffOffset); + } else { + // [S ... W ... R ... E] + validData = rptr + platformHost->captureBufInfo.trafBufSize; + if (validData < platformHost->captureBufInfo.cirBufSize) { + rxData->buf = (char *)(platformHost->captureBufInfo.virtAddr) + rptr; + *tranferSize = platformHost->captureBufInfo.trafBufSize; + *buffOffset = rptr + *tranferSize; + } else { + rxData->buf = (char *)(platformHost->captureBufInfo.virtAddr) + rptr; + *tranferSize = platformHost->captureBufInfo.cirBufSize - rptr; + *buffOffset = 0; + } + AUDIO_DRIVER_LOG_DEBUG("tranferSize : %d rptrReg.u32 : %d ", *tranferSize, rptr); + } + + AUDIO_DRIVER_LOG_DEBUG("rptrReg = [0x%08x], wptrReg = [0x%08x], max size = [%u]", + rptr, wptr, platformHost->captureBufInfo.trafBufSize); + + return HDF_SUCCESS; +} + +int32_t PlatformRead(const struct AudioCard *card, struct AudioRxData *rxData) +{ + unsigned int buffOffset; + struct PlatformHost *platformHost = NULL; + int devId; + unsigned int tranferSize; + + if (rxData == NULL || card == NULL || card->rtd == NULL || card->rtd->platform == NULL) { + AUDIO_DRIVER_LOG_ERR("param is null."); + return HDF_FAILURE; + } + + platformHost = PlatformHostFromDevice(card->rtd->platform->device); + if (platformHost == NULL) { + AUDIO_DRIVER_LOG_ERR("PlatformHostFromDevice: fail."); + return HDF_FAILURE; + } + devId = platformHost->captureBufInfo.chnId; + + OsalMutexLock(&platformHost->captureBufInfo.buffMutex); + if (platformHost->captureBufInfo.virtAddr == NULL) { + AUDIO_DRIVER_LOG_ERR("PlatformWrite: capture data buffer is not initialized."); + OsalMutexUnlock(&platformHost->captureBufInfo.buffMutex); + return HDF_FAILURE; + } + + if (UpdateReadBuffData(platformHost, &tranferSize, &buffOffset, rxData) != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("UpdateReadBuffData failed."); + OsalMutexUnlock(&platformHost->captureBufInfo.buffMutex); + return HDF_FAILURE; + } + OsalMutexUnlock(&platformHost->captureBufInfo.buffMutex); + + if (rxData->status == ENUM_CIR_BUFF_EMPTY) { + AUDIO_DRIVER_LOG_DEBUG("not available data wait a minute."); + return HDF_SUCCESS; + } + + if (!platformHost->pcmInfo.isBigEndian) { + if (AudioDataBigEndianChange(rxData->buf, tranferSize, platformHost->pcmInfo.bitWidth) != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("AudioDataBigEndianChange: failed."); + return HDF_FAILURE; + } + } + + rxData->frames = tranferSize / platformHost->pcmInfo.frameSize; + rxData->bufSize = tranferSize; + rxData->status = ENUM_CIR_BUFF_NORMAL; + + if (buffOffset >= platformHost->captureBufInfo.cirBufSize) { + buffOffset = 0; + } + + if (AipHalSetBuffRptr(devId, buffOffset) != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("AipHalSetBuffRptr failed."); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +int32_t PlatformRenderStart(const struct AudioCard *card) +{ + int ret; + struct PlatformHost *platformHost = NULL; + + ret = PlatformCreatePlatformHost(card, &platformHost); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("PlatformCreatePlatformHost failed."); + return HDF_FAILURE; + } + + platformHost->renderBufInfo.runStatus = 1; + platformHost->renderBufInfo.enable = 0; + ShowAllAcodecRegister(); + ShowAllAiaoRegister(); + + AUDIO_DRIVER_LOG_INFO("audio render start"); + return HDF_SUCCESS; +} + +int32_t PlatformCaptureStart(const struct AudioCard *card) +{ + int ret; + struct PlatformHost *platformHost = NULL; + + ret = PlatformCreatePlatformHost(card, &platformHost); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("PlatformCreatePlatformHost failed."); + return HDF_FAILURE; + } + + AipHalSetRxStart(platformHost->captureBufInfo.chnId, HI_TRUE); + ShowAllAcodecRegister(); + ShowAllAiaoRegister(); + AUDIO_DRIVER_LOG_INFO("audio capture start"); + return HDF_SUCCESS; +} + +int32_t PlatformRenderStop(const struct AudioCard *card) +{ + int ret; + struct PlatformHost *platformHost = NULL; + + ret = PlatformCreatePlatformHost(card, &platformHost); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("PlatformCreatePlatformHost failed."); + return HDF_FAILURE; + } + + OsalMutexLock(&platformHost->renderBufInfo.buffMutex); + platformHost->renderBufInfo.runStatus = 0; + AopHalSetTxStart(platformHost->renderBufInfo.chnId, HI_FALSE); + ret = AudioRenderBuffFree(platformHost); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("AudioRenderBuffFree failed."); + OsalMutexUnlock(&platformHost->renderBufInfo.buffMutex); + return HDF_FAILURE; + } + OsalMutexUnlock(&platformHost->renderBufInfo.buffMutex); + AUDIO_DRIVER_LOG_INFO("audio stream stop"); + + return HDF_SUCCESS; +} + +int32_t PlatformCaptureStop(const struct AudioCard *card) +{ + int ret; + struct PlatformHost *platformHost = NULL; + + ret = PlatformCreatePlatformHost(card, &platformHost); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("PlatformCreatePlatformHost failed."); + return HDF_FAILURE; + } + OsalMutexLock(&platformHost->captureBufInfo.buffMutex); + AipHalSetRxStart(platformHost->captureBufInfo.chnId, HI_FALSE); + ret = AudioCaptureBuffFree(platformHost); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("AudioCaptureBuffFree failed."); + OsalMutexUnlock(&platformHost->captureBufInfo.buffMutex); + return HDF_FAILURE; + } + OsalMutexUnlock(&platformHost->captureBufInfo.buffMutex); + AUDIO_DRIVER_LOG_INFO("audio stream stop"); + return HDF_SUCCESS; +} + +int32_t PlatformCapturePause(const struct AudioCard *card) +{ + int ret; + struct PlatformHost *platformHost = NULL; + + ret = PlatformCreatePlatformHost(card, &platformHost); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("PlatformCreatePlatformHost failed."); + return HDF_FAILURE; + } + + AipHalSetRxStart(platformHost->captureBufInfo.chnId, HI_FALSE); + AUDIO_DRIVER_LOG_INFO("audio stream pause"); + return HDF_SUCCESS; +} + +int32_t PlatformRenderPause(const struct AudioCard *card) +{ + int ret; + struct PlatformHost *platformHost = NULL; + + ret = PlatformCreatePlatformHost(card, &platformHost); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("PlatformCreatePlatformHost failed."); + return HDF_FAILURE; + } + + platformHost->renderBufInfo.runStatus = 0; + AopHalSetTxStart(platformHost->renderBufInfo.chnId, HI_FALSE); + + AUDIO_DRIVER_LOG_INFO("audio stream pause"); + return HDF_SUCCESS; +} + +int32_t PlatformRenderResume(const struct AudioCard *card) +{ + int ret = PlatformRenderStart(card); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("PlatformRenderResume failed."); + return HDF_FAILURE; + } + AUDIO_DRIVER_LOG_INFO("audio stream resume"); + return HDF_SUCCESS; +} + +int32_t PlatformCaptureResume(const struct AudioCard *card) +{ + int ret; + (void)card; + ret = PlatformCaptureStart(card); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("PlatformCaptureStart failed."); + return HDF_FAILURE; + } + AUDIO_DRIVER_LOG_INFO("audio stream resume"); + return HDF_SUCCESS; +} + +struct AudioPlatformOps g_platformDeviceOps = { + .HwParams = PlatformHwParams, + .Write = PlatformWrite, + .Read = PlatformRead, + .RenderPrepare = PlatformRenderPrepare, + .CapturePrepare = PlatformCapturePrepare, + .RenderStart = PlatformRenderStart, + .CaptureStart = PlatformCaptureStart, + .RenderStop = PlatformRenderStop, + .CaptureStop = PlatformCaptureStop, + .RenderPause = PlatformRenderPause, + .CapturePause = PlatformCapturePause, + .RenderResume = PlatformRenderResume, + .CaptureResume = PlatformCaptureResume, +}; + +struct PlatformData g_platformData = { + .PlatformInit = AudioPlatformDeviceInit, + .ops = &g_platformDeviceOps, +}; + +static int32_t PlatformGetServiceName(const struct HdfDeviceObject *device) +{ + const struct DeviceResourceNode *node = NULL; + struct DeviceResourceIface *drsOps = NULL; + int32_t ret; + + if (device == NULL) { + AUDIO_DRIVER_LOG_ERR("para is NULL."); + return HDF_FAILURE; + } + + node = device->property; + if (node == NULL) { + AUDIO_DRIVER_LOG_ERR("node is NULL."); + return HDF_FAILURE; + } + + drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); + if (drsOps == NULL || drsOps->GetString == NULL) { + AUDIO_DRIVER_LOG_ERR("get drsops object instance fail!"); + return HDF_FAILURE; + } + + ret = drsOps->GetString(node, "serviceName", &g_platformData.drvPlatformName, 0); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("read serviceName fail!"); + return ret; + } + + return HDF_SUCCESS; +} + +static int32_t PlatformDriverInit(struct HdfDeviceObject *device) +{ + int32_t ret; + + AUDIO_DRIVER_LOG_DEBUG("entry.\n"); + struct PlatformHost *platformHost = NULL; + + if (device == NULL) { + AUDIO_DRIVER_LOG_ERR("device is NULL."); + return HDF_ERR_INVALID_OBJECT; + } + + ret = PlatformGetServiceName(device); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("get service name fail."); + return ret; + } + + ret = AudioSocDeviceRegister(device, (void *)&g_platformData, AUDIO_PLATFORM_DEVICE); + if (ret != HDF_SUCCESS) { + AUDIO_DRIVER_LOG_ERR("register dai fail."); + return ret; + } + + platformHost = (struct PlatformHost *)device->service; + if (NULL != platformHost) { + OsalMutexInit(&platformHost->renderBufInfo.buffMutex); + OsalMutexInit(&platformHost->captureBufInfo.buffMutex); + } + + AUDIO_DRIVER_LOG_DEBUG("success.\n"); + return HDF_SUCCESS; +} + +static void PlatformDriverRelease(struct HdfDeviceObject *device) +{ + struct PlatformHost *platformHost = NULL; + + if (device == NULL) { + AUDIO_DRIVER_LOG_ERR("device is NULL"); + return; + } + + platformHost = (struct PlatformHost *)device->service; + if (platformHost == NULL) { + AUDIO_DRIVER_LOG_ERR("platformHost is NULL"); + return; + } + + OsalMutexDestroy(&platformHost->renderBufInfo.buffMutex); + OsalMutexDestroy(&platformHost->captureBufInfo.buffMutex); + OsalMemFree(platformHost); +} + +/* HdfDriverEntry definitions */ +struct HdfDriverEntry g_platformDriverEntry = { + .moduleVersion = 1, + .moduleName = "DMA_HI3516", + .Bind = PlatformDriverBind, + .Init = PlatformDriverInit, + .Release = PlatformDriverRelease, +}; +HDF_INIT(g_platformDriverEntry); diff --git a/model/audio/dispatch/include/audio_control_dispatch.h b/model/audio/dispatch/include/audio_control_dispatch.h new file mode 100755 index 000000000..cbaaf488b --- /dev/null +++ b/model/audio/dispatch/include/audio_control_dispatch.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2020-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. + */ + +#ifndef AUDIO_CONTROL_DISPATCH_H +#define AUDIO_CONTROL_DISPATCH_H + +#include "audio_host.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + + +#define AUDIODRV_CTRL_ELEM_TYPE_INTEGER 2 /* integer type */ + +enum ControlDispMethodCmd { + AUDIODRV_CTRL_IOCTRL_ELEM_INFO, + AUDIODRV_CTRL_IOCTRL_ELEM_READ, + AUDIODRV_CTRL_IOCTRL_ELEM_WRITE, + AUDIODRV_CTRL_IOCTRL_ELEM_BUTT, +}; + +typedef int32_t (*ControlDispCmdHandle)(struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply); + +struct ControlDispCmdHandleList { + enum ControlDispMethodCmd cmd; + ControlDispCmdHandle func; +}; + +struct ControlHost { + struct IDeviceIoService service; + struct HdfDeviceObject *device; + void *priv; +}; + +static inline struct ControlHost *ControlHostFromDevice(struct HdfDeviceObject *device) +{ + return (device == NULL) ? NULL : (struct ControlHost *)device->service; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + +#endif /* AUDIO_CONTROL_H */ diff --git a/model/audio/dispatch/include/audio_stream_dispatch.h b/model/audio/dispatch/include/audio_stream_dispatch.h new file mode 100755 index 000000000..105504476 --- /dev/null +++ b/model/audio/dispatch/include/audio_stream_dispatch.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2020-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. + */ + +#ifndef AUDIO_STREAM_DISP_H +#define AUDIO_STREAM_DISP_H + +#include "audio_host.h" +#include "codec_adapter.h" +#include "platform_adapter.h" +#include "dai_adapter.h" +#include "dsp_adapter.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +#define AUDIO_SERVICE_NAME_MAX_LEN 32 + +enum StreamDispMethodCmd { + AUDIO_DRV_PCM_IOCTRL_HW_PARAMS, + AUDIO_DRV_PCM_IOCTRL_RENDER_PREPARE, + AUDIO_DRV_PCM_IOCTRL_CAPTURE_PREPARE, + AUDIO_DRV_PCM_IOCTRL_WRITE, + AUDIO_DRV_PCM_IOCTRL_READ, + AUDIO_DRV_PCM_IOCTRL_RENDER_START, + AUDIO_DRV_PCM_IOCTRL_RENDER_STOP, + AUDIO_DRV_PCM_IOCTRL_CAPTURE_START, + AUDIO_DRV_PCM_IOCTRL_CAPTURE_STOP, + AUDIO_DRV_PCM_IOCTRL_RENDER_PAUSE, + AUDIO_DRV_PCM_IOCTRL_CAPTURE_PAUSE, + AUDIO_DRV_PCM_IOCTRL_RENDER_RESUME, + AUDIO_DRV_PCM_IOCTRL_CAPTURE_RESUME, + AUDIO_DRV_PCM_IOCTRL_DSP_DECODE, + AUDIO_DRV_PCM_IOCTRL_DSP_ENCODE, + AUDIO_DRV_PCM_IOCTRL_DSP_EQUALIZER, + AUDIO_DRV_PCM_IOCTRL_BUTT, +}; + +typedef int32_t (*StreamDispCmdHandle)(struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply); + +struct StreamDispCmdHandleList { + enum StreamDispMethodCmd cmd; + StreamDispCmdHandle func; +}; + +struct StreamHost { + struct IDeviceIoService service; + struct HdfDeviceObject *device; + void *priv; +}; + +static inline struct StreamHost *StreamHostFromDevice(struct HdfDeviceObject *device) +{ + return (device == NULL) ? NULL : (struct StreamHost *)device->service; +} + +int32_t StreamDispatch(struct HdfDeviceIoClient *client, int cmdId, + struct HdfSBuf *data, struct HdfSBuf *reply); +void StreamHostDestroy(struct StreamHost *host); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + +#endif /* AUDIO_STREAM_DISP_H */ diff --git a/model/audio/dispatch/src/audio_control_dispatch.c b/model/audio/dispatch/src/audio_control_dispatch.c new file mode 100755 index 000000000..0f264c553 --- /dev/null +++ b/model/audio/dispatch/src/audio_control_dispatch.c @@ -0,0 +1,333 @@ +/* + * Copyright (c) 2020-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_control_dispatch.h" +#include "audio_sapm.h" + +#define HDF_LOG_TAG audio_control_dispatch + +static struct AudioKcontrol *AudioGetKctrlInstance(const struct AudioCtrlElemId *ctrlElemId) +{ + struct AudioKcontrol *kctrl = NULL; + struct AudioCard *audioCard = NULL; + + if (ctrlElemId == NULL) { + ADM_LOG_ERR("input params check error: ctrlElemId is NULL."); + return NULL; + } + + audioCard = GetCardInstance(ctrlElemId->cardServiceName); + if (audioCard == NULL) { + ADM_LOG_ERR("get kcontrol instance fail!"); + return NULL; + } + + DLIST_FOR_EACH_ENTRY(kctrl, &audioCard->controls, struct AudioKcontrol, list) { + if (strcmp(kctrl->name, ctrlElemId->itemName) != 0) { + continue; + } + if (kctrl->iface != ctrlElemId->iface) { + continue; + } + return kctrl; + } + return NULL; +} + +static int32_t ControlHostElemInfoSub(struct HdfSBuf *rspData, struct AudioCtrlElemId id) +{ + int32_t result; + struct AudioKcontrol *kctrl = NULL; + struct AudioCtrlElemInfo elemInfo; + if (rspData == NULL) { + ADM_LOG_ERR("Input rspData is null."); + return HDF_FAILURE; + } + kctrl = AudioGetKctrlInstance(&id); + if (kctrl == NULL || kctrl->Info == NULL) { + ADM_LOG_ERR("Find kctrl or Info fail!"); + return HDF_FAILURE; + } + + (void)memset_s(&elemInfo, sizeof(struct AudioCtrlElemInfo), 0, sizeof(struct AudioCtrlElemInfo)); + result = kctrl->Info(kctrl, &elemInfo); + if (result != HDF_SUCCESS) { + ADM_LOG_ERR("Get control info fail result=%d", result); + return HDF_FAILURE; + } + + if (!HdfSbufWriteInt32(rspData, elemInfo.type)) { + ADM_LOG_ERR("Write response data type failed!"); + return HDF_FAILURE; + } + if (!HdfSbufWriteInt32(rspData, elemInfo.max)) { + ADM_LOG_ERR("Write response data max failed!"); + return HDF_FAILURE; + } + if (!HdfSbufWriteInt32(rspData, elemInfo.min)) { + ADM_LOG_ERR("Write response data min failed!"); + return HDF_FAILURE; + } + if (!HdfSbufWriteUint32(rspData, elemInfo.count)) { + ADM_LOG_ERR("Write response data count failed!"); + return HDF_FAILURE; + } + ADM_LOG_DEBUG("success."); + return HDF_SUCCESS; +} + +static int32_t ControlHostElemInfo(struct HdfDeviceIoClient *client, struct HdfSBuf *reqData, struct HdfSBuf *rspData) +{ + struct AudioCtrlElemId id; + ADM_LOG_DEBUG("entry."); + + if ((client == NULL) || (reqData == NULL)) { + ADM_LOG_ERR("Input ElemInfo params check error: client=%p, reqData=%p.", client, reqData); + return HDF_FAILURE; + } + + (void)memset_s(&id, sizeof(struct AudioCtrlElemId), 0, sizeof(struct AudioCtrlElemId)); + if (!HdfSbufReadInt32(reqData, &id.iface)) { + ADM_LOG_ERR("Read ElemInfo request id failed!"); + return HDF_FAILURE; + } + + if (!(id.cardServiceName = HdfSbufReadString(reqData))) { + ADM_LOG_ERR("Read ElemInfo request cardServiceName failed!"); + return HDF_FAILURE; + } + + if (!(id.itemName = HdfSbufReadString(reqData))) { + ADM_LOG_ERR("Read ElemInfo request itemName failed!"); + return HDF_FAILURE; + } + + if (ControlHostElemInfoSub(rspData, id)) { + ADM_LOG_ERR("ControlHostElemInfoSub failed!"); + return HDF_FAILURE; + } + + return HDF_SUCCESS; +} + +static int32_t ControlHostElemRead(struct HdfDeviceIoClient *client, struct HdfSBuf *reqData, struct HdfSBuf *rspData) +{ + struct AudioKcontrol *kctrl = NULL; + struct AudioCtrlElemValue elemValue; + struct AudioCtrlElemId id; + int32_t result; + ADM_LOG_DEBUG("entry."); + + if ((client == NULL) || (reqData == NULL) || (rspData == NULL)) { + ADM_LOG_ERR("Input ElemRead params check error: client=%p, reqData=%p, rspData=%p.", client, reqData, rspData); + return HDF_FAILURE; + } + + (void)memset_s(&id, sizeof(struct AudioCtrlElemId), 0, sizeof(struct AudioCtrlElemId)); + if (!HdfSbufReadInt32(reqData, &id.iface)) { + ADM_LOG_ERR("ElemRead request id failed!"); + return HDF_FAILURE; + } + + if (!(id.cardServiceName = HdfSbufReadString(reqData))) { + ADM_LOG_ERR("ElemRead request cardServiceName failed!"); + return HDF_FAILURE; + } + + if (!(id.itemName = HdfSbufReadString(reqData))) { + ADM_LOG_ERR("ElemRead request itemName failed!"); + return HDF_FAILURE; + } + + kctrl = AudioGetKctrlInstance(&id); + if (kctrl == NULL || kctrl->Get == NULL) { + ADM_LOG_ERR("Find kctrl or Get fail."); + return HDF_FAILURE; + } + + (void)memset_s(&elemValue, sizeof(struct AudioCtrlElemValue), 0, sizeof(struct AudioCtrlElemValue)); + result = kctrl->Get(kctrl, &elemValue); + if (result != HDF_SUCCESS) { + ADM_LOG_ERR("Get elemValue fail result=%d", result); + return HDF_FAILURE; + } + + if (!HdfSbufWriteInt32(rspData, elemValue.value[0])) { + ADM_LOG_ERR("Write response data value[0]=%d failed!", elemValue.value[0]); + return HDF_FAILURE; + } + if (!HdfSbufWriteInt32(rspData, elemValue.value[1])) { + ADM_LOG_ERR("Write response data value[1]=%d failed!", elemValue.value[1]); + return HDF_FAILURE; + } + ADM_LOG_DEBUG("success."); + return HDF_SUCCESS; +} + +static int32_t ControlHostElemWrite(struct HdfDeviceIoClient *client, struct HdfSBuf *reqData, struct HdfSBuf *rspData) +{ + struct AudioKcontrol *kctrl = NULL; + struct AudioCtrlElemValue elemValue; + int32_t result; + ADM_LOG_DEBUG("entry."); + + if ((client == NULL) || (reqData == NULL)) { + ADM_LOG_ERR("Input params check error: client=%p, reqData=%p.", client, reqData); + return HDF_FAILURE; + } + (void)rspData; + + (void)memset_s(&elemValue, sizeof(struct AudioCtrlElemValue), 0, sizeof(struct AudioCtrlElemValue)); + if (!HdfSbufReadInt32(reqData, &elemValue.value[0])) { + ADM_LOG_ERR("Read request elemValue failed!"); + return HDF_FAILURE; + } + + if (!HdfSbufReadInt32(reqData, &elemValue.id.iface)) { + ADM_LOG_ERR("Read request id failed!"); + return HDF_FAILURE; + } + + if (!(elemValue.id.cardServiceName = HdfSbufReadString(reqData))) { + ADM_LOG_ERR("Read request cardServiceName failed!"); + return HDF_FAILURE; + } + + if (!(elemValue.id.itemName = HdfSbufReadString(reqData))) { + ADM_LOG_ERR("Read request itemName failed!"); + return HDF_FAILURE; + } + + kctrl = AudioGetKctrlInstance(&elemValue.id); + if (kctrl == NULL || kctrl->Put == NULL) { + ADM_LOG_ERR("Find kctrl or Put fail!"); + return HDF_FAILURE; + } + + result = kctrl->Put(kctrl, &elemValue); + if (result != HDF_SUCCESS) { + ADM_LOG_ERR("Get control value fail result=%d", result); + return HDF_FAILURE; + } + ADM_LOG_DEBUG("success."); + return HDF_SUCCESS; +} + +static struct ControlDispCmdHandleList g_controlDispCmdHandle[] = { + {AUDIODRV_CTRL_IOCTRL_ELEM_INFO, ControlHostElemInfo}, + {AUDIODRV_CTRL_IOCTRL_ELEM_READ, ControlHostElemRead}, + {AUDIODRV_CTRL_IOCTRL_ELEM_WRITE, ControlHostElemWrite}, +}; + +static int32_t ControlDispatch(struct HdfDeviceIoClient *client, int cmdId, + struct HdfSBuf *data, struct HdfSBuf *reply) +{ + unsigned int i; + + if ((client == NULL) || (data == NULL)) { + ADM_LOG_ERR("Input params check error: client=%p, data=%p.", client, data); + return HDF_FAILURE; + } + + if (cmdId >= AUDIODRV_CTRL_IOCTRL_ELEM_BUTT || cmdId < 0) { + ADM_LOG_ERR("Invalid [cmdId=%d].", cmdId); + return HDF_FAILURE; + } + + AudioSapmRefreshTime(true); + for (i = 0; i < ARRAY_SIZE(g_controlDispCmdHandle); ++i) { + if ((cmdId == (int)(g_controlDispCmdHandle[i].cmd)) && (g_controlDispCmdHandle[i].func != NULL)) { + return g_controlDispCmdHandle[i].func(client, data, reply); + } + } + return HDF_FAILURE; +} + +static struct ControlHost *ControlHostCreateAndBind(struct HdfDeviceObject *device) +{ + struct ControlHost *controlHost = NULL; + + if (device == NULL) { + ADM_LOG_ERR("Input params check error: device is NULL."); + return NULL; + } + + controlHost = (struct ControlHost *)OsalMemCalloc(sizeof(*controlHost)); + if (controlHost == NULL) { + ADM_LOG_ERR("Malloc controlHost fail!"); + return NULL; + } + controlHost->device = device; + device->service = &controlHost->service; + return controlHost; +} + +static int32_t AudioControlBind(struct HdfDeviceObject *device) +{ + struct ControlHost *controlHost = NULL; + ADM_LOG_DEBUG("entry."); + + if (device == NULL) { + ADM_LOG_ERR("Input params check error: device is NULL."); + return HDF_FAILURE; + } + + controlHost = ControlHostCreateAndBind(device); + if (controlHost == NULL) { + ADM_LOG_ERR("controlHost is NULL."); + return HDF_FAILURE; + } + + controlHost->service.Dispatch = ControlDispatch; + + ADM_LOG_INFO("success."); + return HDF_SUCCESS; +} + +static int32_t AudioControlInit(struct HdfDeviceObject *device) +{ + (void)device; + ADM_LOG_INFO("success."); + return HDF_SUCCESS; +} + +static void ControlHostDestroy(struct ControlHost *host) +{ + if (host == NULL) { + ADM_LOG_ERR("Input params check error: host is NULL."); + return; + } + OsalMemFree(host); +} + +static void AudioControlRelease(struct HdfDeviceObject *device) +{ + struct ControlHost *controlHost = NULL; + + if (device == NULL) { + ADM_LOG_ERR("Input params check error: device is NULL."); + return; + } + + controlHost = ControlHostFromDevice(device); + if (controlHost == NULL) { + ADM_LOG_ERR("controlHost is NULL."); + return; + } + ControlHostDestroy(controlHost); +} + +/* HdfDriverEntry definitions */ +struct HdfDriverEntry g_audioControlEntry = { + .moduleVersion = 1, + .moduleName = "HDF_AUDIO_CONTROL", + .Bind = AudioControlBind, + .Init = AudioControlInit, + .Release = AudioControlRelease, +}; +HDF_INIT(g_audioControlEntry); diff --git a/model/audio/dispatch/src/audio_stream_dispatch.c b/model/audio/dispatch/src/audio_stream_dispatch.c new file mode 100755 index 000000000..171fc5205 --- /dev/null +++ b/model/audio/dispatch/src/audio_stream_dispatch.c @@ -0,0 +1,1068 @@ +/* + * Copyright (c) 2020-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_stream_dispatch.h" + +#define HDF_LOG_TAG audio_stream_dispatch + +int32_t HwCpuDaiDispatch(struct AudioCard *audioCard, struct AudioPcmHwParams *params) +{ + if ((audioCard == NULL) || (params == NULL)) { + ADM_LOG_ERR("CpuDai input param is NULL."); + return HDF_FAILURE; + } + + struct AudioPcmRuntime *rtd = audioCard->rtd; + if (rtd == NULL) { + ADM_LOG_ERR("CpuDai audioCard rtd is NULL."); + return HDF_FAILURE; + } + + struct DaiDevice *cpuDai = rtd->cpuDai; + if (cpuDai == NULL || cpuDai->devData == NULL || cpuDai->devData->ops == NULL) { + ADM_LOG_ERR("cpuDai param is NULL."); + return HDF_FAILURE; + } + + /* If there are HwParams function, it will be executed directly. + * If not, skip the if statement and execute in sequence. + */ + if (cpuDai->devData->ops->HwParams != NULL) { + int ret = cpuDai->devData->ops->HwParams(audioCard, params, cpuDai); + if (ret < 0) { + ADM_LOG_ERR("cpuDai hardware params fail ret=%d", ret); + return HDF_ERR_IO; + } + } + + return HDF_SUCCESS; +} + +int32_t HwCodecDaiDispatch(struct AudioCard *audioCard, struct AudioPcmHwParams *params) +{ + if ((audioCard == NULL) || (params == NULL)) { + ADM_LOG_ERR("CodecDai input param is NULL."); + return HDF_FAILURE; + } + + struct AudioPcmRuntime *rtd = audioCard->rtd; + if (rtd == NULL) { + ADM_LOG_ERR("CodecDai audioCard rtd is NULL."); + return HDF_FAILURE; + } + struct DaiDevice *codecDai = rtd->codecDai; + if (codecDai == NULL) { + codecDai = rtd->accessoryDai; + } + if (codecDai == NULL || codecDai->devData == NULL || codecDai->devData->ops == NULL) { + ADM_LOG_ERR("codecDai param is NULL."); + return HDF_FAILURE; + } + + /* If there are HwParams function, it will be executed directly. + * If not, skip the if statement and execute in sequence. + */ + if (codecDai->devData->ops->HwParams != NULL) { + int ret = codecDai->devData->ops->HwParams(audioCard, params, codecDai); + if (ret < 0) { + ADM_LOG_ERR("codecDai hardware params fail ret=%d", ret); + return HDF_ERR_IO; + } + } + + return HDF_SUCCESS; +} + +int32_t HwPlatfromDispatch(struct AudioCard *audioCard, struct AudioPcmHwParams *params) +{ + if ((audioCard == NULL) || (params == NULL)) { + ADM_LOG_ERR("Platfrom input param is NULL."); + return HDF_FAILURE; + } + + struct AudioPcmRuntime *rtd = audioCard->rtd; + if (rtd == NULL) { + ADM_LOG_ERR("audioCard rtd is NULL."); + return HDF_FAILURE; + } + + struct PlatformDevice *platform = rtd->platform; + if (platform == NULL || platform->devData == NULL || platform->devData->ops == NULL) { + ADM_LOG_ERR("platform param is NULL."); + return HDF_FAILURE; + } + + /* If there are HwParams function, it will be executed directly. + * If not, skip the if statement and execute in sequence. + */ + if (platform->devData->ops->HwParams != NULL) { + int ret = platform->devData->ops->HwParams(audioCard, params); + if (ret < 0) { + ADM_LOG_ERR("platform hardware params fail ret=%d", ret); + return HDF_ERR_IO; + } + } + + return HDF_SUCCESS; +} + +int32_t HwParamsDispatch(struct AudioCard *audioCard, struct AudioPcmHwParams *params) +{ + if ((audioCard == NULL) || (params == NULL)) { + ADM_LOG_ERR("input param is NULL."); + return HDF_FAILURE; + } + + /* Traverse through each driver method; Enter if you have, if not, exectue in order */ + if (HwCodecDaiDispatch(audioCard, params) || + HwCpuDaiDispatch(audioCard, params) || + HwPlatfromDispatch(audioCard, params)) { + ADM_LOG_ERR("hardware params fail."); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +static int32_t HwParamsDataAnalysis(struct HdfSBuf *reqData, struct AudioPcmHwParams *params) +{ + if ((reqData == NULL) || (params == NULL)) { + ADM_LOG_ERR(" input param is NULL."); + return HDF_FAILURE; + } + + if (!HdfSbufReadUint32(reqData, ¶ms->streamType)) { + ADM_LOG_ERR("read request streamType failed!"); + return HDF_FAILURE; + } + if (!HdfSbufReadUint32(reqData, ¶ms->channels)) { + ADM_LOG_ERR("read request channels failed!"); + return HDF_FAILURE; + } + if (!HdfSbufReadUint32(reqData, ¶ms->rate)) { + ADM_LOG_ERR("read request rate failed!"); + return HDF_FAILURE; + } + if (!HdfSbufReadUint32(reqData, ¶ms->periodSize)) { + ADM_LOG_ERR("read request periodSize failed!"); + return HDF_FAILURE; + } + if (!HdfSbufReadUint32(reqData, ¶ms->periodCount)) { + ADM_LOG_ERR("read request periodCount failed!"); + return HDF_FAILURE; + } + if (!HdfSbufReadUint32(reqData, (uint32_t *)¶ms->format)) { + ADM_LOG_ERR("read request format failed!"); + return HDF_FAILURE; + } + if (!(params->cardServiceName = HdfSbufReadString(reqData))) { + ADM_LOG_ERR("read request cardServiceName failed!"); + return HDF_FAILURE; + } + if (!HdfSbufReadUint32(reqData, ¶ms->period)) { + HDF_LOGE("read request perid failed!"); + return HDF_FAILURE; + } + + if (!HdfSbufReadUint32(reqData, ¶ms->frameSize)) { + HDF_LOGE("read request frameSize failed!"); + return HDF_FAILURE; + } + + if (!HdfSbufReadUint32(reqData, (uint32_t *)¶ms->isBigEndian)) { + HDF_LOGE("read request isBigEndian failed!"); + return HDF_FAILURE; + } + + if (!HdfSbufReadUint32(reqData, (uint32_t *)¶ms->isSignedData)) { + HDF_LOGE("read request isSignedData failed!"); + return HDF_FAILURE; + } + + if (!HdfSbufReadUint32(reqData, ¶ms->startThreshold)) { + HDF_LOGE("read request startThreshold failed!"); + return HDF_FAILURE; + } + + if (!HdfSbufReadUint32(reqData, ¶ms->stopThreshold)) { + HDF_LOGE("read request stopThreshold failed!"); + return HDF_FAILURE; + } + + if (!HdfSbufReadUint32(reqData, ¶ms->silenceThreshold)) { + HDF_LOGE("read request silenceThreshold failed!"); + return HDF_FAILURE; + } + + return HDF_SUCCESS; +} + +int32_t StreamHostHwParams(struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply) +{ + struct AudioPcmHwParams params; + struct StreamHost *streamHost = NULL; + struct AudioCard *audioCard = NULL; + char *cardName = NULL; + int ret; + ADM_LOG_DEBUG("entry."); + + if ((client == NULL) || (data == NULL)) { + ADM_LOG_ERR("input param is NULL."); + return HDF_FAILURE; + } + (void)reply; + + streamHost = StreamHostFromDevice(client->device); + if (streamHost == NULL) { + ADM_LOG_ERR("renderHost is NULL"); + return HDF_FAILURE; + } + + cardName = (char *)OsalMemCalloc(sizeof(char) * BUFF_SIZE_MAX); + if (cardName == NULL) { + ADM_LOG_ERR("malloc cardServiceName fail!"); + return HDF_FAILURE; + } + streamHost->priv = cardName; + + (void)memset_s(¶ms, sizeof(struct AudioPcmHwParams), 0, sizeof(struct AudioPcmHwParams)); + ret = HwParamsDataAnalysis(data, ¶ms); + if (ret != HDF_SUCCESS) { + ADM_LOG_ERR("hwparams data analysis failed ret=%d", ret); + return HDF_FAILURE; + } + + if (memcpy_s(cardName, BUFF_SIZE_MAX, params.cardServiceName, BUFF_SIZE_MAX) != EOK) { + ADM_LOG_ERR("memcpy cardName failed."); + return HDF_FAILURE; + } + + audioCard = GetCardInstance(params.cardServiceName); + if (audioCard == NULL) { + ADM_LOG_ERR("get card instance fail."); + return HDF_FAILURE; + } + + ret = HwParamsDispatch(audioCard, ¶ms); + if (ret != HDF_SUCCESS) { + ADM_LOG_ERR("hwparams dispatch failed ret=%d", ret); + return HDF_FAILURE; + } + ADM_LOG_DEBUG("success."); + return HDF_SUCCESS; +} + +static struct AudioCard *StreamHostGetCardInstance(const struct HdfDeviceIoClient *client) +{ + char *cardName = NULL; + struct StreamHost *streamHost = NULL; + struct AudioCard *audioCard = NULL; + + if (client == NULL) { + ADM_LOG_ERR("input param is NULL."); + return NULL; + } + + streamHost = StreamHostFromDevice(client->device); + if (streamHost == NULL) { + ADM_LOG_ERR("streamHost is NULL"); + return NULL; + } + + cardName = (char *)streamHost->priv; + if (cardName == NULL) { + ADM_LOG_ERR("streamHost priv is NULL."); + return NULL; + } + + audioCard = GetCardInstance(cardName); + if (audioCard == NULL) { + ADM_LOG_ERR("get card instance fail."); + return NULL; + } + + return audioCard; +} + +int32_t StreamHostCapturePrepare(struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply) +{ + struct AudioPcmRuntime *rtd = NULL; + struct PlatformDevice *platform = NULL; + struct AudioCard *audioCard = NULL; + int ret; + ADM_LOG_DEBUG("entry."); + + if (client == NULL) { + ADM_LOG_ERR("CapturePrepare input param is NULL."); + return HDF_FAILURE; + } + + (void)data; + (void)reply; + + audioCard = StreamHostGetCardInstance(client); + if (audioCard == NULL || audioCard->rtd == NULL) { + ADM_LOG_ERR("CapturePrepare get card instance or rtd fail."); + return HDF_FAILURE; + } + rtd = audioCard->rtd; + + platform = rtd->platform; + if (platform == NULL || platform->devData == NULL || platform->devData->ops == NULL || + platform->devData->ops->CapturePrepare == NULL) { + ADM_LOG_ERR("audioCard rtd platform is NULL."); + return HDF_FAILURE; + } + + ret = platform->devData->ops->CapturePrepare(audioCard); + if (ret != HDF_SUCCESS) { + ADM_LOG_ERR("platform CapturePrepare fail ret=%d", ret); + return HDF_ERR_IO; + } + + ADM_LOG_DEBUG("success."); + return HDF_SUCCESS; +} + +int32_t StreamHostRenderPrepare(struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply) +{ + struct AudioPcmRuntime *rtd = NULL; + struct PlatformDevice *platform = NULL; + struct AudioCard *audioCard = NULL; + int ret; + ADM_LOG_DEBUG("entry."); + + if (client == NULL) { + ADM_LOG_ERR("RenderPrepare input param is NULL."); + return HDF_FAILURE; + } + + (void)data; + (void)reply; + + audioCard = StreamHostGetCardInstance(client); + if (audioCard == NULL || audioCard->rtd == NULL) { + ADM_LOG_ERR("RenderPrepare get card instance or rtd fail."); + return HDF_FAILURE; + } + rtd = audioCard->rtd; + + platform = rtd->platform; + if (platform == NULL || platform->devData == NULL || platform->devData->ops == NULL || + platform->devData->ops->RenderPrepare == NULL) { + ADM_LOG_ERR("audioCard rtd platform is NULL."); + return HDF_FAILURE; + } + + ret = platform->devData->ops->RenderPrepare(audioCard); + if (ret != HDF_SUCCESS) { + ADM_LOG_ERR("platform RenderPrepare fail ret=%d", ret); + return HDF_ERR_IO; + } + + ADM_LOG_DEBUG("success."); + return HDF_SUCCESS; +} + +static int32_t StreamTransferWrite(struct AudioCard *audioCard, struct AudioTxData *transfer) +{ + struct PlatformDevice *platform = NULL; + int32_t ret; + + if (audioCard == NULL || audioCard->rtd == NULL || transfer == NULL) { + ADM_LOG_ERR("input param is NULL."); + return HDF_FAILURE; + } + + platform = audioCard->rtd->platform; + if (platform == NULL || platform->devData == NULL || platform->devData->ops == NULL || + platform->devData->ops->Write == NULL) { + ADM_LOG_ERR("audioCard platform is NULL."); + return HDF_FAILURE; + } + + ret = platform->devData->ops->Write(audioCard, transfer); + if (ret != HDF_SUCCESS) { + ADM_LOG_ERR("platform write fail ret=%d", ret); + return HDF_FAILURE; + } + + return HDF_SUCCESS; +} + +int32_t StreamHostWrite(struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply) +{ + struct AudioTxData transfer; + struct AudioCard *audioCard = NULL; + int32_t ret; + uint32_t dataSize = 0; + ADM_LOG_DEBUG("entry."); + + if (client == NULL || reply == NULL) { + ADM_LOG_ERR("input param is NULL."); + return HDF_FAILURE; + } + + if (!HdfSbufReadUint32(data, (uint32_t *)&(transfer.frames))) { + ADM_LOG_ERR("read request frames failed!"); + return HDF_FAILURE; + } + if (!HdfSbufReadBuffer(data, (const void **)&(transfer.buf), &dataSize)) { + ADM_LOG_ERR("read request buf failed!"); + return HDF_FAILURE; + } + + audioCard = StreamHostGetCardInstance(client); + if (audioCard == NULL || audioCard->rtd == NULL) { + ADM_LOG_ERR("get card instance or rtd fail."); + return HDF_FAILURE; + } + + ret = StreamTransferWrite(audioCard, &transfer); + if (ret != HDF_SUCCESS) { + ADM_LOG_ERR("write reg value fail ret=%d", ret); + return HDF_FAILURE; + } + + if (!HdfSbufWriteUint32(reply, (uint32_t)(transfer.status))) { + ADM_LOG_ERR("read response status failed!"); + return HDF_FAILURE; + } + ADM_LOG_DEBUG("success."); + return HDF_SUCCESS; +} + +int32_t StreamHostRead(struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply) +{ + struct AudioPcmRuntime *rtd = NULL; + struct PlatformDevice *platform = NULL; + struct AudioCard *audioCard = NULL; + struct AudioRxData rxData; + int ret; + ADM_LOG_DEBUG("entry."); + + if (client == NULL || reply == NULL) { + ADM_LOG_ERR("input param is NULL."); + return HDF_FAILURE; + } + (void)data; + + audioCard = StreamHostGetCardInstance(client); + if (audioCard == NULL || audioCard->rtd == NULL) { + ADM_LOG_ERR("get card instance or rtd fail."); + return HDF_FAILURE; + } + rtd = audioCard->rtd; + + platform = rtd->platform; + if (platform == NULL || platform->devData == NULL || + platform->devData->ops == NULL || platform->devData->ops->Read == NULL) { + ADM_LOG_ERR("audioCard rtd platform is NULL."); + return HDF_FAILURE; + } + + ret = platform->devData->ops->Read(audioCard, &rxData); + if (ret != HDF_SUCCESS) { + ADM_LOG_ERR("platform read fail ret=%d", ret); + return HDF_FAILURE; + } + + if (!HdfSbufWriteUint32(reply, (uint32_t)(rxData.status))) { + ADM_LOG_ERR("write request data status failed!"); + return HDF_FAILURE; + } + + if (!HdfSbufWriteBuffer(reply, rxData.buf, (uint32_t)(rxData.bufSize))) { + ADM_LOG_ERR("write request data buf failed!"); + return HDF_FAILURE; + } + + if (!HdfSbufWriteUint32(reply, (uint32_t)(rxData.frames))) { + ADM_LOG_ERR("write frames failed!"); + return HDF_FAILURE; + } + + ADM_LOG_DEBUG("success."); + return HDF_SUCCESS; +} + +int32_t StreamHostRenderStart(struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply) +{ + struct AudioPcmRuntime *rtd = NULL; + struct PlatformDevice *platform = NULL; + struct AudioCard *audioCard = NULL; + int ret; + ADM_LOG_DEBUG("entry."); + + if (client == NULL) { + ADM_LOG_ERR("RenderStart input param is NULL."); + return HDF_FAILURE; + } + + (void)data; + (void)reply; + + audioCard = StreamHostGetCardInstance(client); + if (audioCard == NULL || audioCard->rtd == NULL) { + ADM_LOG_ERR("RenderStart get card instance or rtd fail."); + return HDF_FAILURE; + } + rtd = audioCard->rtd; + + platform = rtd->platform; + if (platform == NULL || platform->devData == NULL || platform->devData->ops == NULL || + platform->devData->ops->RenderStart == NULL) { + ADM_LOG_ERR("audioCard rtd platform is NULL."); + return HDF_FAILURE; + } + + ret = platform->devData->ops->RenderStart(audioCard); + if (ret != HDF_SUCCESS) { + ADM_LOG_ERR("platform render start fail ret=%d", ret); + return HDF_ERR_IO; + } + + ADM_LOG_INFO("success."); + return HDF_SUCCESS; +} + +int32_t StreamHostCaptureStart(struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply) +{ + struct AudioPcmRuntime *rtd = NULL; + struct PlatformDevice *platform = NULL; + struct AudioCard *audioCard = NULL; + int ret; + ADM_LOG_DEBUG("entry."); + + if (client == NULL) { + ADM_LOG_ERR("CaptureStart input param is NULL."); + return HDF_FAILURE; + } + + (void)data; + (void)reply; + + audioCard = StreamHostGetCardInstance(client); + if (audioCard == NULL || audioCard->rtd == NULL) { + ADM_LOG_ERR("CaptureStart get card instance or rtd fail."); + return HDF_FAILURE; + } + rtd = audioCard->rtd; + + platform = rtd->platform; + if (platform == NULL || platform->devData == NULL || platform->devData->ops == NULL || + platform->devData->ops->CaptureStart == NULL) { + ADM_LOG_ERR("audioCard rtd platform is NULL."); + return HDF_FAILURE; + } + + ret = platform->devData->ops->CaptureStart(audioCard); + if (ret != HDF_SUCCESS) { + ADM_LOG_ERR("platform capture start fail ret=%d", ret); + return HDF_ERR_IO; + } + + ADM_LOG_INFO("success."); + return HDF_SUCCESS; +} + +int32_t StreamHostRenderStop(struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply) +{ + struct AudioPcmRuntime *rtd = NULL; + struct PlatformDevice *platform = NULL; + struct AudioCard *audioCard = NULL; + int ret; + ADM_LOG_DEBUG("entry."); + + if (client == NULL) { + ADM_LOG_ERR("RenderStop input param is NULL."); + return HDF_FAILURE; + } + + (void)data; + (void)reply; + + audioCard = StreamHostGetCardInstance(client); + if (audioCard == NULL || audioCard->rtd == NULL) { + ADM_LOG_ERR("RenderStop get card instance or rtd fail."); + return HDF_FAILURE; + } + rtd = audioCard->rtd; + + platform = rtd->platform; + if (platform == NULL || platform->devData == NULL || platform->devData->ops == NULL || + platform->devData->ops->RenderStop == NULL) { + ADM_LOG_ERR("audioCard rtd platform is NULL."); + return HDF_FAILURE; + } + + ret = platform->devData->ops->RenderStop(audioCard); + if (ret != HDF_SUCCESS) { + ADM_LOG_ERR("platform render stop fail ret=%d", ret); + return HDF_ERR_IO; + } + + ADM_LOG_INFO("success."); + return HDF_SUCCESS; +} + +int32_t StreamHostCaptureStop(struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply) +{ + struct AudioPcmRuntime *rtd = NULL; + struct PlatformDevice *platform = NULL; + struct AudioCard *audioCard = NULL; + int ret; + ADM_LOG_DEBUG("entry."); + + if (client == NULL) { + ADM_LOG_ERR("CaptureStop input param is NULL."); + return HDF_FAILURE; + } + + (void)data; + (void)reply; + + audioCard = StreamHostGetCardInstance(client); + if (audioCard == NULL || audioCard->rtd == NULL) { + ADM_LOG_ERR("CaptureStop get card instance or rtd fail."); + return HDF_FAILURE; + } + rtd = audioCard->rtd; + + platform = rtd->platform; + if (platform == NULL || platform->devData == NULL || platform->devData->ops == NULL || + platform->devData->ops->CaptureStop == NULL) { + ADM_LOG_ERR("audioCard rtd platform is NULL."); + return HDF_FAILURE; + } + + ret = platform->devData->ops->CaptureStop(audioCard); + if (ret != HDF_SUCCESS) { + ADM_LOG_ERR("platform capture stop fail ret=%d", ret); + return HDF_ERR_IO; + } + + ADM_LOG_INFO("success."); + return HDF_SUCCESS; +} + +int32_t StreamHostRenderPause(struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply) +{ + struct AudioPcmRuntime *rtd = NULL; + struct PlatformDevice *platform = NULL; + struct AudioCard *audioCard = NULL; + int ret; + ADM_LOG_DEBUG("entry."); + + if (client == NULL) { + ADM_LOG_ERR("RenderPause input param is NULL."); + return HDF_FAILURE; + } + + (void)data; + (void)reply; + + audioCard = StreamHostGetCardInstance(client); + if (audioCard == NULL || audioCard->rtd == NULL) { + ADM_LOG_ERR("RenderPause get card instance or rtd fail."); + return HDF_FAILURE; + } + rtd = audioCard->rtd; + + platform = rtd->platform; + if (platform == NULL || platform->devData == NULL || platform->devData->ops == NULL || + platform->devData->ops->RenderPause == NULL) { + ADM_LOG_ERR("audioCard rtd platform is NULL."); + return HDF_FAILURE; + } + + ret = platform->devData->ops->RenderPause(audioCard); + if (ret != HDF_SUCCESS) { + ADM_LOG_ERR("platform render pause fail ret=%d", ret); + return HDF_ERR_IO; + } + + ADM_LOG_INFO("success."); + return HDF_SUCCESS; +} + +int32_t StreamHostCapturePause(struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply) +{ + struct AudioPcmRuntime *rtd = NULL; + struct PlatformDevice *platform = NULL; + struct AudioCard *audioCard = NULL; + int ret; + ADM_LOG_DEBUG("entry."); + + if (client == NULL) { + ADM_LOG_ERR("CapturePause input param is NULL."); + return HDF_FAILURE; + } + + (void)data; + (void)reply; + + audioCard = StreamHostGetCardInstance(client); + if (audioCard == NULL || audioCard->rtd == NULL) { + ADM_LOG_ERR("CapturePause get card instance or rtd fail."); + return HDF_FAILURE; + } + rtd = audioCard->rtd; + + platform = rtd->platform; + if (platform == NULL || platform->devData == NULL || platform->devData->ops == NULL || + platform->devData->ops->CapturePause == NULL) { + ADM_LOG_ERR("audioCard rtd platform is NULL."); + return HDF_FAILURE; + } + + ret = platform->devData->ops->CapturePause(audioCard); + if (ret != HDF_SUCCESS) { + ADM_LOG_ERR("platform captur pause fail ret=%d", ret); + return HDF_ERR_IO; + } + + ADM_LOG_INFO("success."); + return HDF_SUCCESS; +} + +int32_t StreamHostRenderResume(struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply) +{ + struct AudioPcmRuntime *rtd = NULL; + struct PlatformDevice *platform = NULL; + struct AudioCard *audioCard = NULL; + int ret; + ADM_LOG_DEBUG("entry."); + + if (client == NULL) { + ADM_LOG_ERR("RenderResume input param is NULL."); + return HDF_FAILURE; + } + + (void)data; + (void)reply; + + audioCard = StreamHostGetCardInstance(client); + if (audioCard == NULL || audioCard->rtd == NULL) { + ADM_LOG_ERR("RenderResume get card instance or rtd fail."); + return HDF_FAILURE; + } + rtd = audioCard->rtd; + + platform = rtd->platform; + if (platform == NULL || platform->devData == NULL || platform->devData->ops == NULL || + platform->devData->ops->RenderResume == NULL) { + ADM_LOG_ERR("audioCard rtd platform is NULL."); + return HDF_FAILURE; + } + + ret = platform->devData->ops->RenderResume(audioCard); + if (ret != HDF_SUCCESS) { + ADM_LOG_ERR("platform RenderResume fail ret=%d", ret); + return HDF_ERR_IO; + } + + ADM_LOG_INFO("success."); + return HDF_SUCCESS; +} + +int32_t StreamHostCaptureResume(struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply) +{ + struct AudioPcmRuntime *rtd = NULL; + struct PlatformDevice *platform = NULL; + struct AudioCard *audioCard = NULL; + int ret; + ADM_LOG_DEBUG("entry."); + + if (client == NULL) { + ADM_LOG_ERR("CaptureResume input param is NULL."); + return HDF_FAILURE; + } + + (void)data; + (void)reply; + + audioCard = StreamHostGetCardInstance(client); + if (audioCard == NULL || audioCard->rtd == NULL) { + ADM_LOG_ERR("CaptureResume get card instance or rtd fail."); + return HDF_FAILURE; + } + rtd = audioCard->rtd; + + platform = rtd->platform; + if (platform == NULL || platform->devData == NULL || platform->devData->ops == NULL || + platform->devData->ops->CaptureResume == NULL) { + ADM_LOG_ERR("audioCard rtd platform is NULL."); + return HDF_FAILURE; + } + + ret = platform->devData->ops->CaptureResume(audioCard); + if (ret != HDF_SUCCESS) { + ADM_LOG_ERR("platform CaptureResume fail ret=%d", ret); + return HDF_ERR_IO; + } + + ADM_LOG_INFO("success."); + return HDF_SUCCESS; +} + +int32_t StreamHostDspDecode(struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply) +{ + struct AudioPcmRuntime *rtd = NULL; + struct DspDevice *dspDev = NULL; + struct AudioCard *audioCard = NULL; + int ret; + ADM_LOG_DEBUG("Dsp Decode Entry."); + + if (client == NULL) { + ADM_LOG_ERR("DspDecode input param is NULL."); + return HDF_FAILURE; + } + + (void)reply; + + audioCard = StreamHostGetCardInstance(client); + if (audioCard == NULL || audioCard->rtd == NULL) { + ADM_LOG_ERR("DspDecode get card instance or rtd fail."); + return HDF_FAILURE; + } + rtd = audioCard->rtd; + + dspDev = rtd->dsp; + if (dspDev == NULL || dspDev->devData == NULL || dspDev->devData->decode == NULL) { + ADM_LOG_ERR("audioCard rtd dsp is NULL."); + return HDF_FAILURE; + } + + ret = dspDev->devData->decode(audioCard, (void*)data, dspDev); + if (ret != HDF_SUCCESS) { + ADM_LOG_ERR("DeCode render pause fail ret=%d", ret); + return HDF_ERR_IO; + } + + ADM_LOG_INFO("Decode Success."); + return HDF_SUCCESS; +} + +int32_t StreamHostDspEncode(struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply) +{ + struct AudioPcmRuntime *rtd = NULL; + struct DspDevice *dspDev = NULL; + struct AudioCard *audioCard = NULL; + int ret; + ADM_LOG_DEBUG("Dsp Encode Entry."); + + if (client == NULL) { + ADM_LOG_ERR("DspEncode input param is NULL."); + return HDF_FAILURE; + } + + (void)reply; + + audioCard = StreamHostGetCardInstance(client); + if (audioCard == NULL || audioCard->rtd == NULL) { + ADM_LOG_ERR("DspEncode get card instance or rtd fail."); + return HDF_FAILURE; + } + rtd = audioCard->rtd; + + dspDev = rtd->dsp; + if (dspDev == NULL || dspDev->devData == NULL || dspDev->devData->encode == NULL) { + ADM_LOG_ERR("audioCard rtd dsp is NULL."); + return HDF_FAILURE; + } + + ret = dspDev->devData->encode(audioCard, (void*)data, dspDev); + if (ret != HDF_SUCCESS) { + ADM_LOG_ERR("EnCode render pause fail ret=%d", ret); + return HDF_ERR_IO; + } + + ADM_LOG_INFO("Encode Success."); + return HDF_SUCCESS; +} + +int32_t StreamHostDspEqualizer(struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply) +{ + struct AudioPcmRuntime *rtd = NULL; + struct DspDevice *dspDev = NULL; + struct AudioCard *audioCard = NULL; + int ret; + ADM_LOG_DEBUG("Dsp Equalizer Entry."); + + if (client == NULL) { + ADM_LOG_ERR("DspEqualizer input param is NULL."); + return HDF_FAILURE; + } + + (void)reply; + + audioCard = StreamHostGetCardInstance(client); + if (audioCard == NULL || audioCard->rtd == NULL) { + ADM_LOG_ERR("DspEqualizer get card instance or rtd fail."); + return HDF_FAILURE; + } + rtd = audioCard->rtd; + + dspDev = rtd->dsp; + if (dspDev == NULL || dspDev->devData == NULL || dspDev->devData->Equalizer == NULL) { + ADM_LOG_ERR("audioCard rtd dsp is NULL."); + return HDF_FAILURE; + } + + ret = dspDev->devData->Equalizer(audioCard, (void*)data, dspDev); + if (ret != HDF_SUCCESS) { + ADM_LOG_ERR("Equalizer render pause fail ret=%d", ret); + return HDF_ERR_IO; + } + + ADM_LOG_INFO("Equalizer Success."); + return HDF_SUCCESS; +} + +static struct StreamDispCmdHandleList g_streamDispCmdHandle[] = { + {AUDIO_DRV_PCM_IOCTRL_HW_PARAMS, StreamHostHwParams}, + {AUDIO_DRV_PCM_IOCTRL_RENDER_PREPARE, StreamHostRenderPrepare}, + {AUDIO_DRV_PCM_IOCTRL_CAPTURE_PREPARE, StreamHostCapturePrepare}, + {AUDIO_DRV_PCM_IOCTRL_WRITE, StreamHostWrite}, + {AUDIO_DRV_PCM_IOCTRL_READ, StreamHostRead}, + {AUDIO_DRV_PCM_IOCTRL_RENDER_START, StreamHostRenderStart}, + {AUDIO_DRV_PCM_IOCTRL_RENDER_STOP, StreamHostRenderStop}, + {AUDIO_DRV_PCM_IOCTRL_CAPTURE_START, StreamHostCaptureStart}, + {AUDIO_DRV_PCM_IOCTRL_CAPTURE_STOP, StreamHostCaptureStop}, + {AUDIO_DRV_PCM_IOCTRL_RENDER_PAUSE, StreamHostRenderPause}, + {AUDIO_DRV_PCM_IOCTRL_CAPTURE_PAUSE, StreamHostCapturePause}, + {AUDIO_DRV_PCM_IOCTRL_RENDER_RESUME, StreamHostRenderResume}, + {AUDIO_DRV_PCM_IOCTRL_CAPTURE_RESUME, StreamHostCaptureResume}, + {AUDIO_DRV_PCM_IOCTRL_DSP_DECODE, StreamHostDspDecode}, + {AUDIO_DRV_PCM_IOCTRL_DSP_ENCODE, StreamHostDspEncode}, + {AUDIO_DRV_PCM_IOCTRL_DSP_EQUALIZER, StreamHostDspEqualizer}, +}; + +int32_t StreamDispatch(struct HdfDeviceIoClient *client, int cmdId, + struct HdfSBuf *data, struct HdfSBuf *reply) +{ + unsigned int i; + + if ((client == NULL) || (data == NULL) || (reply == NULL)) { + return HDF_ERR_INVALID_PARAM; + } + + if (cmdId >= AUDIO_DRV_PCM_IOCTRL_BUTT || cmdId < 0) { + ADM_LOG_ERR("invalid [cmdId=%d]", cmdId); + return HDF_FAILURE; + } + + for (i = 0; i < sizeof(g_streamDispCmdHandle) / sizeof(g_streamDispCmdHandle[0]); ++i) { + if ((cmdId == (int)(g_streamDispCmdHandle[i].cmd)) && (g_streamDispCmdHandle[i].func != NULL)) { + return g_streamDispCmdHandle[i].func(client, data, reply); + } + } + return HDF_FAILURE; +} + +static struct StreamHost *StreamHostCreateAndBind(struct HdfDeviceObject *device) +{ + if (device == NULL) { + return NULL; + } + + struct StreamHost *streamHost = (struct StreamHost *)OsalMemCalloc(sizeof(*streamHost)); + if (streamHost == NULL) { + ADM_LOG_ERR("malloc host fail!"); + return NULL; + } + streamHost->device = device; + device->service = &streamHost->service; + return streamHost; +} + +static int32_t AudioStreamBind(struct HdfDeviceObject *device) +{ + ADM_LOG_DEBUG("entry!"); + if (device == NULL) { + return HDF_ERR_INVALID_PARAM; + } + + struct StreamHost *streamHost = StreamHostCreateAndBind(device); + if (streamHost->device == NULL) { + ADM_LOG_ERR("StreamHostCreateAndBind failed"); + return HDF_FAILURE; + } + + streamHost->service.Dispatch = StreamDispatch; + + ADM_LOG_INFO("success!"); + return HDF_SUCCESS; +} + +static int32_t AudioStreamInit(struct HdfDeviceObject *device) +{ + struct StreamHost *streamHost = NULL; + + if (device == NULL) { + ADM_LOG_ERR("device is NULL"); + return HDF_FAILURE; + } + ADM_LOG_DEBUG("entry."); + + streamHost = StreamHostFromDevice(device); + if (streamHost == NULL) { + ADM_LOG_ERR("renderHost is NULL"); + return HDF_FAILURE; + } + + ADM_LOG_INFO("Success!"); + return HDF_SUCCESS; +} + +void StreamParamDestroy(struct AudioPcmHwParams *params) +{ + if (params == NULL) { + return; + } + + OsalMemFree(params); + params = NULL; +} + +void StreamHostDestroy(struct StreamHost *host) +{ + if (host == NULL) { + return; + } + + OsalMemFree(host); + host = NULL; +} + +static void AudioStreamRelease(struct HdfDeviceObject *device) +{ + if (device == NULL) { + ADM_LOG_ERR("device is NULL"); + return; + } + + struct StreamHost *streamHost = StreamHostFromDevice(device); + if (streamHost == NULL) { + ADM_LOG_ERR("renderHost is NULL"); + return; + } + + StreamParamDestroy(streamHost->priv); + StreamHostDestroy(streamHost); +} + +/* HdfDriverEntry definitions */ +struct HdfDriverEntry g_audioStreamEntry = { + .moduleVersion = 1, + .moduleName = "HDF_AUDIO_STREAM", + .Bind = AudioStreamBind, + .Init = AudioStreamInit, + .Release = AudioStreamRelease, +}; +HDF_INIT(g_audioStreamEntry); diff --git a/model/audio/dispatch/test/unittest/common/audio_stream_dispatch_test.cpp b/model/audio/dispatch/test/unittest/common/audio_stream_dispatch_test.cpp new file mode 100755 index 000000000..d1ddb68a3 --- /dev/null +++ b/model/audio/dispatch/test/unittest/common/audio_stream_dispatch_test.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2020-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_common_test.h" +#include +#include "hdf_uhdf_test.h" + +using namespace testing::ext; + +class AudioStreamDispatchTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); +}; + +void AudioStreamDispatchTest::SetUpTestCase() +{ + HdfTestOpenService(); +} + +void AudioStreamDispatchTest::TearDownTestCase() +{ + HdfTestCloseService(); +} + +void AudioStreamDispatchTest::SetUp() +{ +} + +void AudioStreamDispatchTest::TearDown() +{ +} + +HWTEST_F(AudioStreamDispatchTest, AudioStreamDispatchTest001, TestSize.Level0) +{ + struct HdfTestMsg msg = {g_testAudioType, TESTSTREAMDISPATCH, -1}; + EXPECT_EQ(0, HdfTestSendMsgToService(&msg)); +} + +HWTEST_F(AudioStreamDispatchTest, AudioStreamDispatchTest002, TestSize.Level0) +{ + struct HdfTestMsg msg = {g_testAudioType, TESTSTREAMDESTORY, -1}; + EXPECT_EQ(0, HdfTestSendMsgToService(&msg)); +} diff --git a/model/audio/sapm/include/audio_sapm.h b/model/audio/sapm/include/audio_sapm.h new file mode 100755 index 000000000..71be01f08 --- /dev/null +++ b/model/audio/sapm/include/audio_sapm.h @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2020-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. + */ + +#ifndef AUDIO_SAPM_H +#define AUDIO_SAPM_H + +#include "audio_core.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +#define SAPM_POLL_TIME 10000 /* 10s */ +#define SAPM_SLEEP_TIME (3 * 60000) /* 3min */ + +#define MIXER_REG_ADDR 10 /* mixer address -- Temporarily defined as this value */ + +#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 + +/* sapm widget types */ +enum AudioSapmType { + AUDIO_SAPM_INPUT = 0, /* input pin */ + AUDIO_SAPM_OUTPUT, /* output pin */ + AUDIO_SAPM_MUX, /* selects 1 analog signal from many inputs */ + AUDIO_SAPM_VIRT_MUX, /* virtual version of snd_soc_dapm_mux */ + AUDIO_SAPM_VALUE_MUX, /* selects 1 analog signal from many inputs */ + AUDIO_SAPM_MIXER, /* mixes several analog signals together */ + AUDIO_SAPM_MIXER_NAMED_CTRL, /* mixer with named controls */ + AUDIO_SAPM_PGA, /* programmable gain/attenuation (volume) */ + AUDIO_SAPM_OUT_DRV, /* output driver */ + AUDIO_SAPM_ADC, /* analog to digital converter */ + AUDIO_SAPM_DAC, /* digital to analog converter */ + AUDIO_SAPM_MICBIAS, /* microphone bias (power) */ + AUDIO_SAPM_MIC, /* microphone */ + AUDIO_SAPM_HP, /* headphones */ + AUDIO_SAPM_SPK, /* speaker */ + AUDIO_SAPM_LINE, /* line input/output */ + AUDIO_SAPM_ANALOG_SWITCH, /* analog switch */ + AUDIO_SAPM_VMID, /* codec bias/vmid - to minimise pops */ + AUDIO_SAPM_PRE, /* machine specific pre component - exec first */ + AUDIO_SAPM_POST, /* machine specific post component - exec last */ + AUDIO_SAPM_SUPPLY, /* power/clock supply */ + AUDIO_SAPM_AIF_IN, /* audio interface input */ + AUDIO_SAPM_AIF_OUT, /* audio interface output */ +}; + +/* component has no PM register bit */ +#define AUDIO_SAPM_NOPM (-1) + +/* dapm stream operations */ +#define AUDIO_SAPM_STREAM_NOP 0x0 +#define AUDIO_SAPM_STREAM_START 0x1 +#define AUDIO_SAPM_STREAM_STOP 0x2 +#define AUDIO_SAPM_STREAM_SUSPEND 0x4 +#define AUDIO_SAPM_STREAM_RESUME 0x8 +#define AUDIO_SAPM_STREAM_PAUSE_PUSH 0x10 +#define AUDIO_SAPM_STREAM_PAUSE_RELEASE 0x20 + +/* sapm event types */ +#define AUDIO_SAPM_PRE_PMU 0x1 /* before component power up */ +#define AUDIO_SAPM_POST_PMU 0x2 /* after component power up */ +#define AUDIO_SAPM_PRE_PMD 0x4 /* before component power down */ +#define AUDIO_SAPM_POST_PMD 0x8 /* after component power down */ +#define AUDIO_SAPM_PRE_REG 0x10 /* before audio path setup */ +#define AUDIO_SAPM_POST_REG 0x20 /* after audio path setup */ +#define AUDIO_SAPM_PRE_POST_PMD (AUDIO_SAPM_PRE_PMD | AUDIO_SAPM_POST_PMD) + +enum AudioBiasLevel { + AUDIO_BIAS_OFF = 0, + AUDIO_BIAS_STANDBY = 1, + AUDIO_BIAS_PREPARE = 2, + AUDIO_BIAS_ON = 3, +}; + +/* SAPM context */ +struct AudioSapmContext { + int32_t componentNum; /* number of components in this context */ + enum AudioBiasLevel biasLevel; + enum AudioBiasLevel suspendBiasLevel; + + struct CodecDevice *codec; /* parent codec */ + struct PlatformDevice *platform; /* parent platform */ + struct AudioCard *card; /* parent card */ + + /* used during SAPM updates */ + enum AudioBiasLevel targetBiasLevel; + struct DListHead list; +}; + +/* enumerated kcontrol */ +struct AudioEnumKcontrol { + uint32_t reg; + uint32_t reg2; + uint8_t shiftLeft; + uint8_t shiftRight; + uint32_t max; + uint32_t mask; + const char * const *texts; + const uint32_t *values; + void *sapm; +}; + +/* sapm audio path between two components */ +struct AudioSapmpath { + char *name; + + /* source (input) and sink (output) components */ + struct AudioSapmComponent *source; + struct AudioSapmComponent *sink; + struct AudioKcontrol *kcontrol; + + /* status */ + uint8_t connect; /* source and sink components are connected */ + uint8_t walked; /* path has been walked */ + uint8_t weak; /* path ignored for power management */ + + int32_t (*connected)(struct AudioSapmComponent *source, struct AudioSapmComponent *sink); + + struct DListHead listSource; + struct DListHead listSink; + struct DListHead list; +}; + +/* sapm component */ +struct AudioSapmComponent { + enum AudioSapmType sapmType; + char *componentName; /* component name */ + char *streamName; /* stream name */ + struct AudioSapmContext *sapm; + struct CodecDevice *codec; /* parent codec */ + struct AccessoryDevice *accessory; /* parent accessory */ + struct PlatformDevice *platform; /* parent platform */ + + /* sapm control */ + int16_t reg; /* negative reg = no direct sapm */ + uint8_t shift; /* bits to shift */ + uint8_t invert; /* invert the power bit */ + uint8_t mask; + uint8_t connected; /* connected codec pin */ + uint8_t external; /* has external components */ + uint8_t active; /* active stream on DAC, ADC's */ + uint8_t newPower; /* power checked this run */ + uint8_t power; + uint8_t newCpt; + + /* external events */ + uint16_t eventFlags; /* flags to specify event types */ + int32_t (*Event)(struct AudioSapmComponent*, struct AudioKcontrol *, int32_t); + + /* power check callback */ + int32_t (*PowerCheck)(const struct AudioSapmComponent *); + + /* kcontrols that relate to this component */ + int32_t kcontrolsNum; + struct AudioKcontrol *kcontrolNews; + struct AudioKcontrol **kcontrols; + + struct DListHead list; + + /* component input and outputs */ + struct DListHead sources; + struct DListHead sinks; + + /* used during SAPM updates */ + struct DListHead powerList; + struct DListHead dirty; + + /* reserve clock interface */ + int32_t (*PowerClockOp)(struct AudioSapmComponent *); +}; + +struct AudioSapmRoute { + const char *sink; + const char *control; + const char *source; + + /* Note: currently only supported for links where source is a supply */ + uint32_t (*Connected)(struct AudioSapmComponent *source, + struct AudioSapmComponent *sink); +}; + +int32_t AudioSapmNewComponents(struct AudioCard *audioCard, + const struct AudioSapmComponent *component, int32_t cptMaxNum); +int32_t AudioSapmAddRoutes(struct AudioCard *audioCard, + const struct AudioSapmRoute *route, int32_t routeMaxNum); +int32_t AudioSapmNewControls(struct AudioCard *audioCard); +int32_t AudioSapmPowerComponents(struct AudioCard *audioCard); +u64 AudioSapmRefreshTime(bool bRefresh); + +extern int32_t AudioSapmPutCtrlSw(struct AudioKcontrol *kcontrol, struct AudioCtrlElemValue *elemValue); +extern int32_t AudioSapmGetCtrlSw(struct AudioKcontrol *kcontrol, struct AudioCtrlElemValue *elemValue); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + +#endif /* AUDIO_SAPM_H */ diff --git a/model/audio/sapm/src/audio_sapm.c b/model/audio/sapm/src/audio_sapm.c new file mode 100755 index 000000000..201a3c777 --- /dev/null +++ b/model/audio/sapm/src/audio_sapm.c @@ -0,0 +1,1230 @@ +/* + * Copyright (c) 2020-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 "osal_io.h" +#include "osal_time.h" +#include "osal_timer.h" + +#define HDF_LOG_TAG audio_sapm + +static void AudioSapmEnterSleep(uintptr_t para); + +/* power up sequences */ +static int32_t g_audioSapmPowerUpSeq[] = { + [AUDIO_SAPM_PRE] = 0, /* 0 is audio sapm power up sequences */ + [AUDIO_SAPM_SUPPLY] = 1, /* 1 is audio sapm power up sequences */ + [AUDIO_SAPM_MICBIAS] = 2, /* 2 is audio sapm power up sequences */ + [AUDIO_SAPM_AIF_IN] = 3, /* 3 is audio sapm power up sequences */ + [AUDIO_SAPM_AIF_OUT] = 3, /* 3 is audio sapm power up sequences */ + [AUDIO_SAPM_MIC] = 4, /* 4 is audio sapm power up sequences */ + [AUDIO_SAPM_MUX] = 5, /* 5 is audio sapm power up sequences */ + [AUDIO_SAPM_VIRT_MUX] = 5, /* 5 is audio sapm power up sequences */ + [AUDIO_SAPM_VALUE_MUX] = 5, /* 5 is audio sapm power up sequences */ + [AUDIO_SAPM_DAC] = 6, /* 6 is audio sapm power up sequences */ + [AUDIO_SAPM_MIXER] = 7, /* 7 is audio sapm power up sequences */ + [AUDIO_SAPM_MIXER_NAMED_CTRL] = 7, /* 7 is audio sapm power up sequences */ + [AUDIO_SAPM_PGA] = 8, /* 8 is audio sapm power up sequences */ + [AUDIO_SAPM_ADC] = 9, /* 9 is audio sapm power up sequences */ + [AUDIO_SAPM_OUT_DRV] = 10, /* 10 is audio sapm power up sequences */ + [AUDIO_SAPM_HP] = 10, /* 10 is audio sapm power up sequences */ + [AUDIO_SAPM_SPK] = 10, /* 10 is audio sapm power up sequences */ + [AUDIO_SAPM_POST] = 11, /* 11 is audio sapm power up sequences */ +}; + +/* power down sequences */ +static int32_t g_audioSapmPowerDownSeq[] = { + [AUDIO_SAPM_PRE] = 0, /* 0 is audio sapm power down sequences */ + [AUDIO_SAPM_ADC] = 1, /* 1 is audio sapm power down sequences */ + [AUDIO_SAPM_HP] = 2, /* 2 is audio sapm power down sequences */ + [AUDIO_SAPM_SPK] = 2, /* 2 is audio sapm power down sequences */ + [AUDIO_SAPM_OUT_DRV] = 2, /* 2 is audio sapm power down sequences */ + [AUDIO_SAPM_PGA] = 4, /* 4 is audio sapm power down sequences */ + [AUDIO_SAPM_MIXER_NAMED_CTRL] = 5, /* 5 is audio sapm power down sequences */ + [AUDIO_SAPM_MIXER] = 5, /* 5 is audio sapm power down sequences */ + [AUDIO_SAPM_DAC] = 6, /* 6 is audio sapm power down sequences */ + [AUDIO_SAPM_MIC] = 7, /* 7 is audio sapm power down sequences */ + [AUDIO_SAPM_MICBIAS] = 8, /* 8 is audio sapm power down sequences */ + [AUDIO_SAPM_MUX] = 9, /* 9 is audio sapm power down sequences */ + [AUDIO_SAPM_VIRT_MUX] = 9, /* 9 is audio sapm power down sequences */ + [AUDIO_SAPM_VALUE_MUX] = 9, /* 9 is audio sapm power down sequences */ + [AUDIO_SAPM_AIF_IN] = 10, /* 10 is audio sapm power down sequences */ + [AUDIO_SAPM_AIF_OUT] = 10, /* 10 is audio sapm power down sequences */ + [AUDIO_SAPM_SUPPLY] = 11, /* 11 is audio sapm power down sequences */ + [AUDIO_SAPM_POST] = 12, /* 12 is audio sapm power down sequences */ +}; + +static int32_t g_audioSapmIsSleep = 0; +static int32_t g_audioSapmIsStandby = 0; +OSAL_DECLARE_TIMER(g_sleepTimer); + +static int32_t ConnectedInputEndPoint(const struct AudioSapmComponent *cpt) +{ + struct AudioSapmpath *path = NULL; + int32_t count = 0; + int32_t endPointVal = 1; + + if (cpt == NULL) { + ADM_LOG_ERR("input param cpt is NULL."); + return HDF_FAILURE; + } + + switch (cpt->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, &cpt->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 *cpt) +{ + struct AudioSapmpath *path = NULL; + int32_t count = 0; + int32_t endPointVal = 1; + + if (cpt == NULL) { + ADM_LOG_ERR("input param cpt is NULL."); + return HDF_FAILURE; + } + + switch (cpt->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, &cpt->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 *cpt) +{ + int32_t input; + int32_t output; + + if (cpt == NULL) { + ADM_LOG_ERR("input param cpt is NULL."); + return HDF_FAILURE; + } + + input = ConnectedInputEndPoint(cpt); + if (input == HDF_FAILURE) { + ADM_LOG_ERR("input endpoint fail!"); + return HDF_FAILURE; + } + output = ConnectedOutputEndPoint(cpt); + 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 AudioSapmAdcCheckPower(const struct AudioSapmComponent *cpt) +{ + int32_t input; + + if (cpt == NULL) { + ADM_LOG_ERR("input param cpt is NULL."); + return HDF_FAILURE; + } + + if (cpt->active == 0) { + input = AudioSapmGenericCheckPower(cpt); + } else { + input = ConnectedInputEndPoint(cpt); + } + if (input == HDF_FAILURE) { + ADM_LOG_ERR("input endpoint fail!"); + return HDF_FAILURE; + } + return input; +} + +static int AudioSapmDacCheckPower(const struct AudioSapmComponent *cpt) +{ + int32_t output; + + if (cpt == NULL) { + ADM_LOG_ERR("input param cpt is NULL."); + return HDF_FAILURE; + } + + if (cpt->active == 0) { + output = AudioSapmGenericCheckPower(cpt); + } else { + output = ConnectedOutputEndPoint(cpt); + } + if (output == HDF_FAILURE) { + ADM_LOG_ERR("output endpoint fail!"); + return HDF_FAILURE; + } + return output; +} + +static void AudioSampCheckPowerCallback(struct AudioSapmComponent *cpt) +{ + if (cpt == NULL) { + ADM_LOG_ERR("input param cpt is NULL."); + return; + } + + switch (cpt->sapmType) { + case AUDIO_SAPM_ANALOG_SWITCH: + case AUDIO_SAPM_MIXER: + case AUDIO_SAPM_MIXER_NAMED_CTRL: + cpt->PowerCheck = AudioSapmGenericCheckPower; + break; + case AUDIO_SAPM_MUX: + case AUDIO_SAPM_VIRT_MUX: + case AUDIO_SAPM_VALUE_MUX: + cpt->PowerCheck = AudioSapmGenericCheckPower; + break; + case AUDIO_SAPM_ADC: + case AUDIO_SAPM_AIF_OUT: + cpt->PowerCheck = AudioSapmAdcCheckPower; + break; + case AUDIO_SAPM_DAC: + case AUDIO_SAPM_AIF_IN: + cpt->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: + cpt->PowerCheck = AudioSapmGenericCheckPower; + break; + default: + cpt->PowerCheck = AudioSapmGenericCheckPower; + break; + } + + return; +} + +int32_t AudioSapmNewComponent(struct AudioCard *audioCard, const struct AudioSapmComponent *component) +{ + struct AudioSapmComponent *cpt = NULL; + + if ((audioCard == NULL) || (component == NULL)) { + ADM_LOG_ERR("input params check error: audioCard=%p, component=%p.", audioCard, component); + return HDF_FAILURE; + } + + cpt = (struct AudioSapmComponent *)OsalMemCalloc(sizeof(struct AudioSapmComponent)); + if (cpt == NULL) { + ADM_LOG_ERR("malloc cpt fail!"); + return HDF_FAILURE; + } + + if (memcpy_s(cpt, sizeof(struct AudioSapmComponent), component, sizeof(struct AudioSapmComponent)) != EOK) { + ADM_LOG_ERR("memcpy cpt fail!"); + OsalMemFree(cpt); + return HDF_FAILURE; + } + + cpt->componentName = (char *)OsalMemCalloc(strlen(component->componentName) + 1); + if (cpt->componentName == NULL) { + ADM_LOG_ERR("malloc cpt->componentName fail!"); + OsalMemFree(cpt); + return HDF_FAILURE; + } + if (memcpy_s(cpt->componentName, strlen(component->componentName) + 1, + component->componentName, strlen(component->componentName) + 1) != EOK) { + ADM_LOG_ERR("memcpy cpt->componentName fail!"); + OsalMemFree(cpt->componentName); + OsalMemFree(cpt); + return HDF_FAILURE; + } + cpt->codec = audioCard->rtd->codec; + cpt->kcontrolsNum = component->kcontrolsNum; + cpt->active = 0; + AudioSampCheckPowerCallback(cpt); + cpt->PowerClockOp = NULL; + + DListHeadInit(&cpt->sources); + DListHeadInit(&cpt->sinks); + DListHeadInit(&cpt->list); + DListHeadInit(&cpt->dirty); + DListInsertHead(&cpt->list, &audioCard->components); + + cpt->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) || (component == NULL)) { + ADM_LOG_ERR("input params check error: audioCard=%p, component=%p.", audioCard, component); + 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 *cpt, struct AudioSapmpath *path, + const struct AudioEnumKcontrol *enumKtl, int32_t i) +{ + int32_t ret; + uint32_t val; + int32_t item; + uint32_t reg; + uint32_t shift; + + if ((cpt == NULL) || (path == NULL) || (enumKtl == NULL)) { + ADM_LOG_ERR("input MuxSet params check error: cpt=%p, path=%p, enumKtl=%p.", cpt, path, enumKtl); + return; + } + + shift = enumKtl->shiftLeft; + ret = AudioCodecDeviceReadReg(cpt->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 ((strcmp(path->name, enumKtl->texts[i]) == 0) && item == i) { + path->connect = CONNECT_SINK_AND_SOURCE; + } + } + return; +} + +static void MuxValueSetPathStatus(const struct AudioSapmComponent *cpt, struct AudioSapmpath *path, + const struct AudioEnumKcontrol *enumKtl, int32_t i) +{ + int32_t ret; + uint32_t val; + uint32_t item; + uint32_t reg = 0; + uint32_t shift; + if ((cpt == NULL) || (path == NULL) || (enumKtl == NULL)) { + ADM_LOG_ERR("input muxValueSet params check error: cpt=%p, path=%p, enumKtl=%p.", cpt, path, enumKtl); + return; + } + + shift = enumKtl->shiftLeft; + + ret = AudioCodecDeviceReadReg(cpt->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 ((strcmp(path->name, enumKtl->texts[i]) == 0) && item == i) { + path->connect = CONNECT_SINK_AND_SOURCE; + } + } + return; +} + +static void MixerSetPathStatus(const struct AudioSapmComponent *cpt, 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; + + if ((cpt == NULL) || (path == NULL) || (mixerCtrl == NULL)) { + ADM_LOG_ERR("input params check error: cpt=%p, path=%p, mixerCtrl=%p.", cpt, path, mixerCtrl); + return; + } + + reg = mixerCtrl->reg; + shift = mixerCtrl->shift; + mask = mixerCtrl->mask; + invert = mixerCtrl->invert; + + ret = AudioCodecDeviceReadReg(cpt->codec, reg, &curValue); + if (ret != HDF_SUCCESS) { + ADM_LOG_ERR("read reg fail!"); + 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(struct AudioSapmComponent *cpt, struct AudioSapmpath *path, int32_t i) +{ + if ((cpt == NULL) || (path == NULL)) { + ADM_LOG_ERR("input params check error: cpt=%p, path=%p.", cpt, path); + return HDF_FAILURE; + } + switch (cpt->sapmType) { + case AUDIO_SAPM_MIXER: + case AUDIO_SAPM_ANALOG_SWITCH: + case AUDIO_SAPM_MIXER_NAMED_CTRL: { + MixerSetPathStatus(cpt, path, (struct AudioMixerControl *)cpt->kcontrolNews[i].privateValue); + } + break; + case AUDIO_SAPM_MUX: { + MuxSetPathStatus(cpt, path, (struct AudioEnumKcontrol *)cpt->kcontrolNews[i].privateValue, i); + } + break; + case AUDIO_SAPM_VALUE_MUX: { + MuxValueSetPathStatus(cpt, path, (struct AudioEnumKcontrol *)cpt->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; + + 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 (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; + } + + /* check for external components */ + 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 *cpt = NULL; + int32_t ret; + + if ((audioCard == NULL) || (route == NULL)) { + ADM_LOG_ERR("input params check error: audioCard=%p, route=%p.", audioCard, route); + return HDF_FAILURE; + } + + DLIST_FOR_EACH_ENTRY(cpt, &audioCard->components, struct AudioSapmComponent, list) { + if ((cptSource == NULL) && (strcmp(cpt->componentName, route->source) == 0)) { + cptSource = cpt; + continue; + } + if ((cptSink == NULL) && (strcmp(cpt->componentName, route->sink) == 0)) { + cptSink = cpt; + } + 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); + + /* check for external components */ + 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) || (route == NULL)) { + ADM_LOG_ERR("input params check error: audioCard=%p, route=%p.", audioCard, route); + 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(struct AudioSapmComponent *cpt, struct AudioCard *audioCard) +{ + struct AudioSapmpath *path = NULL; + int32_t i; + + if ((cpt == NULL) || (audioCard == NULL)) { + ADM_LOG_ERR("input params check error: cpt=%p, audioCard=%p.", cpt, audioCard); + return HDF_FAILURE; + } + + for (i = 0; i < cpt->kcontrolsNum; i++) { + DLIST_FOR_EACH_ENTRY(path, &cpt->sources, struct AudioSapmpath, listSink) { + if (strcmp(path->name, cpt->kcontrolNews[i].name) != 0) { + continue; + } + + path->kcontrol = AudioAddControl(audioCard, &cpt->kcontrolNews[i]); + if (path->kcontrol == NULL) { + ADM_LOG_ERR("add control fail!"); + return HDF_FAILURE; + } + cpt->kcontrols[i] = path->kcontrol; + DListInsertHead(&cpt->kcontrols[i]->list, &audioCard->controls); + } + } + + return HDF_SUCCESS; +} + +int AudioSapmNewMuxControls(struct AudioSapmComponent *cpt, struct AudioCard *audioCard) +{ + struct AudioKcontrol *kctrl = NULL; + + if (cpt == NULL) { + ADM_LOG_ERR("input param cpt is NULL."); + return HDF_FAILURE; + } + + if (cpt->kcontrolsNum != 1) { + ADM_LOG_ERR("incorrect number of controls."); + return HDF_FAILURE; + } + + kctrl = AudioAddControl(audioCard, &cpt->kcontrolNews[0]); + if (kctrl == NULL) { + ADM_LOG_ERR("add control fail!"); + return HDF_FAILURE; + } + cpt->kcontrols[0] = kctrl; + DListInsertHead(&cpt->kcontrols[0]->list, &audioCard->controls); + + return HDF_SUCCESS; +} + +static void AudioSapmPowerSeqInsert(struct AudioSapmComponent *newCpt, + struct DListHead *list, int8_t isPowerUp) +{ + struct AudioSapmComponent *cpt = NULL; + int32_t *seq = {0}; + + if (newCpt == NULL) { + ADM_LOG_ERR("input param newCpt is NULL."); + return; + } + + if (isPowerUp) { + seq = g_audioSapmPowerUpSeq; + } else { + seq = g_audioSapmPowerDownSeq; + } + + DLIST_FOR_EACH_ENTRY(cpt, list, struct AudioSapmComponent, powerList) { + if ((seq[newCpt->sapmType] - seq[cpt->sapmType]) < 0) { + DListInsertTail(&newCpt->powerList, &cpt->powerList); + return; + } + } + DListInsertTail(&newCpt->powerList, list); + + ADM_LOG_DEBUG("[%s] success.", newCpt->componentName); + return; +} + +static void AudioSapmSetPower(struct AudioCard *audioCard, struct AudioSapmComponent *cpt, + uint8_t power, struct DListHead *upList, struct DListHead *downList) +{ + struct AudioSapmpath *path = NULL; + + if (cpt == NULL) { + ADM_LOG_ERR("input param cpt is NULL."); + return; + } + + DLIST_FOR_EACH_ENTRY(path, &cpt->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, &cpt->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(cpt, upList, power); + } else { + AudioSapmPowerSeqInsert(cpt, downList, power); + } + + cpt->power = power; + return; +} + +static void AudioSapmPowerUpSeqRun(struct DListHead *list) +{ + enum AudioDeviceType deviceType; + struct AudioMixerControl mixerControl; + void *device = NULL; + struct AudioSapmComponent *cpt = NULL; + int32_t ret; + + if (list == NULL) { + ADM_LOG_ERR("input param list is NULL."); + return; + } + + DLIST_FOR_EACH_ENTRY(cpt, list, struct AudioSapmComponent, powerList) { + if ((cpt->reg >= 0) && (cpt->power == SAPM_POWER_DOWN)) { + cpt->power = SAPM_POWER_UP; + mixerControl.reg = cpt->reg; + mixerControl.mask = cpt->mask; + mixerControl.shift = cpt->shift; + if (cpt->codec != NULL && cpt->codec->devData != NULL) { + deviceType = AUDIO_CODEC_DEVICE; + device = cpt->codec; + } else { + deviceType = AUDIO_ACCESSORY_DEVICE; + device = cpt->accessory; + } + ret = AudioUpdateRegBits(deviceType, device, &mixerControl, SAPM_POWER_UP); + if (ret != HDF_SUCCESS) { + ADM_LOG_ERR("update reg bits fail!"); + return; + } + } + } + return; +} + +static void AudioSapmPowerDownSeqRun(struct DListHead *list) +{ + void *device = NULL; + enum AudioDeviceType deviceType; + struct AudioMixerControl mixerControl; + struct AudioSapmComponent *cpt = NULL; + int32_t ret; + + if (list == NULL) { + ADM_LOG_ERR("input param list is NULL."); + return; + } + + DLIST_FOR_EACH_ENTRY(cpt, list, struct AudioSapmComponent, powerList) { + if ((cpt->reg >= 0) && (cpt->power == SAPM_POWER_UP)) { + cpt->power = SAPM_POWER_DOWN; + mixerControl.mask = cpt->mask; + mixerControl.reg = cpt->reg; + mixerControl.shift = cpt->shift; + if (cpt->codec != NULL && cpt->codec->devData != NULL) { + deviceType = AUDIO_CODEC_DEVICE; + device = cpt->codec; + } else { + deviceType = AUDIO_ACCESSORY_DEVICE; + device = cpt->accessory; + } + ret = AudioUpdateRegBits(deviceType, device, &mixerControl, SAPM_POWER_DOWN); + if (ret != HDF_SUCCESS) { + ADM_LOG_ERR("update reg bits fail!"); + return; + } + } + } + + return; +} + +int32_t AudioSapmPowerComponents(struct AudioCard *audioCard) +{ + struct AudioSapmComponent *cpt = NULL; + struct DListHead upList; + struct DListHead downList; + + if (audioCard == NULL) { + ADM_LOG_ERR("input param audioCard is NULL."); + return HDF_FAILURE; + } + + DListHeadInit(&upList); + DListHeadInit(&downList); + + DLIST_FOR_EACH_ENTRY(cpt, &audioCard->sapmDirty, struct AudioSapmComponent, dirty) { + cpt->newPower = cpt->PowerCheck(cpt); + if (cpt->newPower == cpt->power) { + continue; + } + + if (g_audioSapmIsStandby && cpt->PowerClockOp != NULL) { + cpt->PowerClockOp(cpt); + } + + AudioSapmSetPower(audioCard, cpt, cpt->newPower, &upList, &downList); + } + + DLIST_FOR_EACH_ENTRY(cpt, &audioCard->components, struct AudioSapmComponent, list) { + DListRemove(&cpt->dirty); + DListHeadInit(&cpt->dirty); + } + + AudioSapmPowerDownSeqRun(&downList); + AudioSapmPowerUpSeqRun(&upList); + + return HDF_SUCCESS; +} + +static void ReadInitComponentPowerStatus(struct AudioSapmComponent *cpt) +{ + int32_t ret; + uint32_t regVal; + + if (cpt == NULL) { + ADM_LOG_ERR("input param cpt is NULL."); + return; + } + + if (cpt->reg >= 0) { + ret = AudioCodecDeviceReadReg(cpt->codec, cpt->reg, ®Val); + if (ret != HDF_SUCCESS) { + ADM_LOG_ERR("read reg fail!"); + return; + } + regVal &= 1 << cpt->shift; + + if (cpt->invert) { + regVal = !regVal; + } + + if (regVal) { + cpt->power = SAPM_POWER_UP; + } else { + cpt->power = SAPM_POWER_DOWN; + } + } + + return; +} + +void AudioSapmSleep(const struct AudioCard *audioCard) +{ + if (audioCard == NULL) { + ADM_LOG_ERR("input param audioCard is NULL."); + return; + } + + if (g_sleepTimer.realTimer != NULL) { + OsalTimerDelete(&g_sleepTimer); + } + OsalTimerCreate(&g_sleepTimer, SAPM_POLL_TIME, AudioSapmEnterSleep, (uintptr_t)audioCard); + OsalTimerStartLoop(&g_sleepTimer); + AudioSapmRefreshTime(true); + + return; +} + +int32_t AudioSapmNewControls(struct AudioCard *audioCard) +{ + struct AudioSapmComponent *cpt = NULL; + int32_t ret; + + if (audioCard == NULL) { + ADM_LOG_ERR("input param audioCard is NULL."); + return HDF_FAILURE; + } + + DLIST_FOR_EACH_ENTRY(cpt, &audioCard->components, struct AudioSapmComponent, list) { + if (cpt->newCpt) { + continue; + } + if (cpt->kcontrolsNum > 0) { + cpt->kcontrols = OsalMemCalloc(sizeof(struct AudioKcontrol*) * cpt->kcontrolsNum); + if (cpt->kcontrols == NULL) { + ADM_LOG_ERR("malloc kcontrols fail!"); + return HDF_FAILURE; + } + } + + switch (cpt->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(cpt, audioCard); + break; + case AUDIO_SAPM_MUX: + case AUDIO_SAPM_VIRT_MUX: + case AUDIO_SAPM_VALUE_MUX: + ret =AudioSapmNewMuxControls(cpt, audioCard); + break; + default: + ret = HDF_SUCCESS; + break; + } + if (ret != HDF_SUCCESS) { + OsalMemFree(cpt->kcontrols); + ADM_LOG_ERR("sapm new mixer or mux controls fail!"); + return HDF_FAILURE; + } + + ReadInitComponentPowerStatus(cpt); + cpt->newCpt = 1; + DListInsertTail(&cpt->dirty, &audioCard->sapmDirty); + } + + ret = AudioSapmPowerComponents(audioCard); + if (ret != HDF_SUCCESS) { + ADM_LOG_ERR("sapm power component fail!"); + return HDF_FAILURE; + } + + AudioSapmSleep(audioCard); + return HDF_SUCCESS; +} + +static int32_t MixerUpdatePowerStatus(struct AudioKcontrol *kcontrol, uint32_t pathStatus) +{ + struct AudioCard *audioCard = NULL; + struct AudioSapmpath *path = NULL; + int32_t ret; + + if (kcontrol == NULL || kcontrol->pri == NULL) { + ADM_LOG_ERR("input param kcontrol is NULL."); + return HDF_FAILURE; + } + audioCard = (struct AudioCard *)(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; + } + + ret = AudioSapmPowerComponents(audioCard); + if (ret != HDF_SUCCESS) { + ADM_LOG_ERR("sapm power component fail!"); + return HDF_FAILURE; + } + + DLIST_FOR_EACH_ENTRY(path, &audioCard->paths, struct AudioSapmpath, list) { + ADM_LOG_DEBUG("path->sink->componentName = %s, path->source->componentName = %s, \ + path->connect = %d.", + path->sink->componentName, path->source->componentName, path->connect); + } + return HDF_SUCCESS; +} + +int32_t AudioSapmGetCtrlSw(struct AudioKcontrol *kcontrol, struct AudioCtrlElemValue *elemValue) +{ + int32_t ret; + struct CodecDevice *codec = NULL; + struct AudioMixerControl *mixerCtrl = NULL; + uint32_t curValue; + + if (kcontrol == NULL || kcontrol->privateValue <= 0 || elemValue == NULL) { + ADM_LOG_ERR("input params: kcontrol is NULL or elemValue=%p.", elemValue); + return HDF_ERR_INVALID_OBJECT; + } + + codec = AudioKcontrolGetCodec(kcontrol); + if (codec == NULL || codec->devData == NULL || codec->devData->Read == NULL) { + ADM_LOG_ERR("codec device is NULL."); + return HDF_FAILURE; + } + mixerCtrl = (struct AudioMixerControl *)kcontrol->privateValue; + ret = codec->devData->Read(codec, mixerCtrl->reg, &curValue); + if (ret != HDF_SUCCESS) { + ADM_LOG_ERR("sapm Get Ctrl Read fail!"); + return HDF_FAILURE; + } + + curValue = (curValue >> mixerCtrl->shift) & mixerCtrl->mask; + if (curValue > mixerCtrl->max) { + ADM_LOG_ERR("invalid curValue:%d.", curValue); + return HDF_FAILURE; + } + + if (mixerCtrl->invert) { + curValue = mixerCtrl->max - curValue; + } + elemValue->value[0] = curValue; + + return HDF_SUCCESS; +} + +int32_t AudioSapmPutCtrlSwSub(struct AudioKcontrol *kcontrol, struct AudioCtrlElemValue *elemValue, + struct AudioMixerControl *mixerCtrl, int32_t value, uint32_t pathStatus) +{ + int32_t ret = HDF_FAILURE; + void *device = NULL; + enum AudioDeviceType deviceType; + uint32_t curValue; + struct CodecDevice *codec = AudioKcontrolGetCodec(kcontrol); + struct AccessoryDevice *accessory = AudioKcontrolGetAccessory(kcontrol); + + if (kcontrol == NULL || elemValue == NULL || mixerCtrl == NULL) { + ADM_LOG_ERR("parser is fail!"); + return HDF_FAILURE; + } + if (codec != NULL) { + deviceType = AUDIO_CODEC_DEVICE; + device = (void *)codec; + ret = AudioCodecDeviceReadReg(codec, mixerCtrl->reg, &curValue); + } else if (accessory != NULL) { + deviceType = AUDIO_ACCESSORY_DEVICE; + device = (void *)accessory; + ret = AudioAccessoryDeviceReadReg(accessory, mixerCtrl->reg, &curValue); + } + if (ret != HDF_SUCCESS) { + ADM_LOG_ERR("Device read fail!"); + return HDF_FAILURE; + } + curValue &= mixerCtrl->mask << mixerCtrl->shift; + value = (value & mixerCtrl->mask) << mixerCtrl->shift; + if ((curValue != value) || g_audioSapmIsSleep) { + if (MixerUpdatePowerStatus(kcontrol, pathStatus) != HDF_SUCCESS) { + ADM_LOG_ERR("update power status fail!"); + return HDF_FAILURE; + } + if (AudioUpdateRegBits(deviceType, device, mixerCtrl, elemValue->value[0]) != HDF_SUCCESS) { + ADM_LOG_ERR("update reg bits fail!"); + return HDF_FAILURE; + } + } + + return HDF_SUCCESS; +} + +/* 1.first user specify old component -- power down; 2.second user specify new component -- power up */ +int32_t AudioSapmPutCtrlSw(struct AudioKcontrol *kcontrol, struct AudioCtrlElemValue *elemValue) +{ + uint32_t pathStatus; + int32_t value; + struct AudioMixerControl *mixerCtrl = NULL; + + if ((kcontrol == NULL) || (kcontrol->privateValue <= 0) || (elemValue == NULL)) { + ADM_LOG_ERR("input params: kcontrol is NULL or elemValue=%p.", elemValue); + return HDF_ERR_INVALID_OBJECT; + } + mixerCtrl = (struct AudioMixerControl *)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; + } + if (AudioSapmPutCtrlSwSub(kcontrol, elemValue, mixerCtrl, value, pathStatus) == HDF_FAILURE) { + ADM_LOG_ERR("AudioSapmPutCtrlSwSub value is fail."); + return HDF_FAILURE; + } + + return HDF_SUCCESS; +} + + +u64 AudioSapmRefreshTime(bool bRefresh) +{ + static u64 time = 0; + + if (bRefresh) { + time = OsalGetSysTimeMs(); + g_audioSapmIsSleep = false; + } + return time; +} + +static bool AudioSapmCheckTime(void) +{ + int64_t diffTime = OsalGetSysTimeMs() - AudioSapmRefreshTime(false); + if (diffTime > SAPM_SLEEP_TIME) { + return true; + } else if (diffTime < 0) { + AudioSapmRefreshTime(true); + } + return false; +} + +static void AudioSapmEnterSleepSub(uintptr_t para, struct AudioSapmComponent *cpt) +{ + void *device = NULL; + int i; + enum AudioDeviceType deviceType; + struct DListHead downList; + struct AudioCard *audioCard = (struct AudioCard *)para; + + DListHeadInit(&downList); + DLIST_FOR_EACH_ENTRY(cpt, &audioCard->components, struct AudioSapmComponent, list) { + for (i = 0; (i < cpt->kcontrolsNum) && (cpt->kcontrols != NULL) && (cpt->kcontrols[i] != NULL); i++) { + struct AudioMixerControl *mixerCtrl = (struct AudioMixerControl *)(cpt->kcontrols[i]->privateValue); + if (mixerCtrl != NULL) { + if (cpt->codec != NULL && cpt->codec->devData != NULL) { + deviceType = AUDIO_CODEC_DEVICE; + device = cpt->codec; + } else { + deviceType = AUDIO_ACCESSORY_DEVICE; + device = cpt->accessory; + } + AudioUpdateRegBits(deviceType, device, mixerCtrl, SAPM_POWER_DOWN); + } + } + ReadInitComponentPowerStatus(cpt); + if (cpt->power == SAPM_POWER_UP) { + AudioSapmPowerSeqInsert(cpt, &downList, SAPM_POWER_DOWN); + } + } + AudioSapmPowerDownSeqRun(&downList); + g_audioSapmIsSleep = true; +} + +static void AudioSapmEnterSleep(uintptr_t para) +{ + struct AudioSapmComponent *cpt = NULL; + struct AudioCard *audioCard = (struct AudioCard *)para; + static bool bFirst = true; + + if ((g_audioSapmIsSleep == true) || (audioCard == NULL) || (!AudioSapmCheckTime())) { + return; + } + + if (bFirst) { + bFirst = false; + AudioSapmRefreshTime(true); + return; + } + + DLIST_FOR_EACH_ENTRY(cpt, &audioCard->components, struct AudioSapmComponent, list) { + if (cpt->PowerClockOp != NULL) { + if (g_audioSapmIsStandby == false) { + cpt->PowerClockOp(cpt); + g_audioSapmIsStandby = true; + AudioSapmRefreshTime(true); + } + } + } + if (g_audioSapmIsStandby == true) { + if (!AudioSapmCheckTime()) { + return; + } + g_audioSapmIsStandby = false; + } + + AudioSapmEnterSleepSub(para, cpt); +} diff --git a/model/audio/sapm/test/unittest/common/audio_sapm_test.cpp b/model/audio/sapm/test/unittest/common/audio_sapm_test.cpp new file mode 100755 index 000000000..9e49ea001 --- /dev/null +++ b/model/audio/sapm/test/unittest/common/audio_sapm_test.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2020-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_common_test.h" +#include +#include "hdf_uhdf_test.h" + +using namespace testing::ext; + +class AudioSapmTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); +}; + +void AudioSapmTest::SetUpTestCase() +{ + HdfTestOpenService(); +} + +void AudioSapmTest::TearDownTestCase() +{ + HdfTestCloseService(); +} + +void AudioSapmTest::SetUp() +{ +} + +void AudioSapmTest::TearDown() +{ +} + +HWTEST_F(AudioSapmTest, AudioSapmTest001, TestSize.Level0) +{ + struct HdfTestMsg msg = {g_testAudioType, TESTNEWCOMPONENT, -1}; + EXPECT_EQ(0, HdfTestSendMsgToService(&msg)); +} + +HWTEST_F(AudioSapmTest, AudioSapmTest002, TestSize.Level0) +{ + struct HdfTestMsg msg = {g_testAudioType, TESTADDROUTES, -1}; + EXPECT_EQ(0, HdfTestSendMsgToService(&msg)); +} + +HWTEST_F(AudioSapmTest, AudioSapmTest003, TestSize.Level0) +{ + struct HdfTestMsg msg = {g_testAudioType, TESTNEWCONTROLS, -1}; + EXPECT_EQ(0, HdfTestSendMsgToService(&msg)); +} + +HWTEST_F(AudioSapmTest, AudioSapmTest004, TestSize.Level0) +{ + struct HdfTestMsg msg = {g_testAudioType, TESTPOWERCOMPONET, -1}; + EXPECT_EQ(0, HdfTestSendMsgToService(&msg)); +} + +HWTEST_F(AudioSapmTest, AudioSapmTest005, TestSize.Level0) +{ + struct HdfTestMsg msg = {g_testAudioType, TESTREFRESHTIME, -1}; + EXPECT_EQ(0, HdfTestSendMsgToService(&msg)); +} diff --git a/test/unittest/common/hdf_main_test.c b/test/unittest/common/hdf_main_test.c index ee5e40088..0662cc6c4 100644 --- a/test/unittest/common/hdf_main_test.c +++ b/test/unittest/common/hdf_main_test.c @@ -49,6 +49,9 @@ #if defined(LOSCFG_DRIVERS_HDF_WIFI) || defined(CONFIG_DRIVERS_HDF_WIFI) #include "hdf_wifi_test.h" #endif +#if defined(LOSCFG_DRIVERS_HDF_AUDIO_TEST) || defined(CONFIG_DRIVERS_HDF_AUDIO_TEST) +#include "hdf_audio_test.h" +#endif #define HDF_LOG_TAG hdf_test @@ -90,7 +93,10 @@ HdfTestFuncList g_hdfTestFuncList[] = { { TEST_CONFIG_TYPE, HdfConfigEntry }, { TEST_OSAL_ITEM, HdfOsalEntry }, #if defined(LOSCFG_DRIVERS_HDF_WIFI) || defined(CONFIG_DRIVERS_HDF_WIFI) - {TEST_WIFI_TYPE, HdfWifiEntry} + {TEST_WIFI_TYPE, HdfWifiEntry}, +#endif +#if defined(LOSCFG_DRIVERS_HDF_AUDIO_TEST) || defined(CONFIG_DRIVERS_HDF_AUDIO_TEST) + {TEST_AUDIO_TYPE, HdfAudioEntry}, #endif }; diff --git a/test/unittest/common/hdf_main_test.h b/test/unittest/common/hdf_main_test.h index be051bd93..e2fd3767a 100644 --- a/test/unittest/common/hdf_main_test.h +++ b/test/unittest/common/hdf_main_test.h @@ -67,6 +67,7 @@ typedef enum { TEST_WIFI_TYPE = TEST_WIFI_BEGIN + 1, TEST_WIFI_END = 600, TEST_CONFIG_TYPE = 601, + TEST_AUDIO_TYPE = 701, TEST_HDF_FRAME_END = 800, } HdfTestSubModuleCmd; diff --git a/test/unittest/model/audio/include/audio_core_test.h b/test/unittest/model/audio/include/audio_core_test.h new file mode 100755 index 000000000..f19df51dd --- /dev/null +++ b/test/unittest/model/audio/include/audio_core_test.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2020-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. + */ + +#ifndef AUDIO_CORE_TEST_H +#define AUDIO_CORE_TEST_H + +#include "hdf_types.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +int32_t AudioSocTestRegisterDai(void); +int32_t AudioSocTestRegisterPlatform(void); +int32_t AudioTestRegisterCodec(void); +int32_t AudioTestBindDaiLink(void); +int32_t AudioTestSocDeviceRegister(void); +int32_t AudioTestSocRegisterDsp(void); +int32_t AudioTestRegisterAccessory(void); +int32_t AudioTestUpdateRegBits(void); +int32_t AudioTestAiaoUpdateRegBits(void); +int32_t AudioTestKcontrolGetCodec(void); +int32_t AudioTestAddControls(void); +int32_t AudioTestAddControl(void); +int32_t AudioTestDeviceReadReg(void); +int32_t AudioTestAiaoDeviceReadReg(void); +int32_t AudioTestInfoCtrlSw(void); +int32_t AudioTestGetCtrlSw(void); +int32_t AudioTestPutCtrlSw(void); +int32_t AiaoTestGetCtrlSw(void); +int32_t AiaoTestPutCtrlSw(void); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + +#endif /* AUDIO_CORE_TEST_H */ diff --git a/test/unittest/model/audio/include/audio_host_test.h b/test/unittest/model/audio/include/audio_host_test.h new file mode 100755 index 000000000..e67ff0830 --- /dev/null +++ b/test/unittest/model/audio/include/audio_host_test.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2020-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. + */ + +#ifndef AUDIO_HOST_TEST_H +#define AUDIO_HOST_TEST_H + +#include "hdf_types.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +int32_t AudioKcontrolTestGetCodec(void); +int32_t GetCardTestInstance(void); +int32_t AudioHostTestDestroy(void); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + +#endif /* AUDIO_HOST_TEST_H */ diff --git a/test/unittest/model/audio/include/audio_parse_test.h b/test/unittest/model/audio/include/audio_parse_test.h new file mode 100755 index 000000000..7e45e873b --- /dev/null +++ b/test/unittest/model/audio/include/audio_parse_test.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2020-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. + */ + +#ifndef AUDIO_PARSE_TEST_H +#define AUDIO_PARSE_TEST_H + +#include "hdf_types.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +int32_t AudioFillTestConfigData(void); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + +#endif /* AUDIO_PARSE_TEST_H */ diff --git a/test/unittest/model/audio/include/audio_sapm_test.h b/test/unittest/model/audio/include/audio_sapm_test.h new file mode 100755 index 000000000..6aac0cd81 --- /dev/null +++ b/test/unittest/model/audio/include/audio_sapm_test.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2020-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. + */ + +#ifndef AUDIO_SAPM_TEST_H +#define AUDIO_SAPM_TEST_H + +#include "hdf_types.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" +{ +#endif +#endif +int32_t AudioSapmTestNewComponents(void); +int32_t AudioSapmTestAddRoutes(void); +int32_t AudioSapmTestNewControls(void); +int32_t AudioSapmTestPowerComponents(void); +int32_t AudioSapmTestRefreshTime(void); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif + +#endif diff --git a/test/unittest/model/audio/include/audio_stream_dispatch_test.h b/test/unittest/model/audio/include/audio_stream_dispatch_test.h new file mode 100755 index 000000000..7adadee5c --- /dev/null +++ b/test/unittest/model/audio/include/audio_stream_dispatch_test.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2020-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. + */ + +#ifndef AUDIO_STREAM_DISPATCH_TEST_H +#define AUDIO_STREAM_DISPATCH_TEST_H + +#include "hdf_types.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" +{ +#endif +#endif +int32_t AudioControlDispatchTestStreamDispatch(void); +int32_t AudioControlDispatchTestStreamHostDestroy(void); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif + +#endif diff --git a/test/unittest/model/audio/include/hdf_audio_test.h b/test/unittest/model/audio/include/hdf_audio_test.h new file mode 100755 index 000000000..eef9a1a6b --- /dev/null +++ b/test/unittest/model/audio/include/hdf_audio_test.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2020-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. + */ + +#ifndef HDF_AUDIO_TEST_H +#define HDF_AUDIO_TEST_H + +#include "hdf_main_test.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +typedef enum { + AUDIO_DRIVER_TESTGETCODEC, + AUDIO_DRIVER_TESTGETCARDINSTANCE, + AUDIO_DRIVER_TESTHOSTDESTROY, + AUDIO_DRIVER_TESTGETCCNFIGDATA, + AUDIO_DRIVER_TESTREGISTERDAI, + AUDIO_DRIVER_TESTREGISTERPLATFORM, + AUDIO_DRIVER_TESTREGISTERCODEC, + AUDIO_DRIVER_TESTBINDDAILINK, + AUDIO_DRIVER_TESTDEVICEREGISTER, + AUDIO_DRIVER_TESTREGISTERDSP, + AUDIO_DRIVER_TESTREGISTERACCESSORY, + AUDIO_DRIVER_TESTUPDATEREGBITS, + AUDIO_DRIVER_TESTAIAOUPDATEREGBITS, + AUDIO_DRIVER_TESTKCONTROLGETCODEC, + AUDIO_DRIVER_TESTADDCONTROLS, + AUDIO_DRIVER_TESTADDCONTROL, + AUDIO_DRIVER_TESTDEVICEREADREG, + AUDIO_DRIVER_TESTAIAODEVICEREADREG, + AUDIO_DRIVER_TESTINFOCTRLSW, + AUDIO_DRIVER_TESTGETCTRLSW, + AUDIO_DRIVER_TESTPUTCTRLSW, + AUDIO_DRIVER_TESTAIAOGETCTRLSW, + AUDIO_DRIVER_TESTAIAOPUTCTRLSW, + AUDIO_DRIVER_TESTNEWCOMPONENT, + AUDIO_DRIVER_TESTADDROUTES, + AUDIO_DRIVER_TESTNEWCONTROLS, + AUDIO_DRIVER_TESTPOWERCOMPONET, + AUDIO_DRIVER_TESTREFRESHTIME, + AUDIO_DRIVER_TESTSTREAMDISPATCH, + AUDIO_DRIVER_TESTSTREAMDESTORY, +} HdfAudioTestCaseCmd; + +int32_t HdfAudioEntry(HdfTestMsg *msg); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + +#endif /* HDF_AUDIO_TEST_H */ diff --git a/test/unittest/model/audio/src/audio_core_test.c b/test/unittest/model/audio/src/audio_core_test.c new file mode 100755 index 000000000..ce38ab2d6 --- /dev/null +++ b/test/unittest/model/audio/src/audio_core_test.c @@ -0,0 +1,327 @@ +/* + * Copyright (c) 2020-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_core_test.h" +#include "audio_core.h" + +#define HDF_LOG_TAG audio_core_test + +int32_t AudioSocTestRegisterDai(void) +{ + int32_t ret; + struct HdfDeviceObject *device = NULL; + struct DaiData *data = NULL; + HDF_LOGI("%s: enter", __func__); + + ret = AudioSocRegisterDai(device, data); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: AudioSocRegisterDai fail ret = %d", __func__, ret); + } + + HDF_LOGI("%s: success", __func__); + return HDF_SUCCESS; +} + +int32_t AudioSocTestRegisterPlatform(void) +{ + int32_t ret; + struct HdfDeviceObject *device = NULL; + struct PlatformData *data = NULL; + HDF_LOGI("%s: enter", __func__); + + ret = AudioSocRegisterPlatform(device, data); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: AudioSocRegisterPlatform fail ret = %d", __func__, ret); + } + + HDF_LOGI("%s: success", __func__); + return HDF_SUCCESS; +} + +int32_t AudioTestRegisterCodec(void) +{ + int32_t ret; + struct HdfDeviceObject *device = NULL; + struct CodecData *codecData = NULL; + struct DaiData *daiData = NULL; + HDF_LOGI("%s: enter", __func__); + + ret = AudioRegisterCodec(device, codecData, daiData); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: AudioRegisterCodec fail ret = %d", __func__, ret); + } + + HDF_LOGI("%s: success", __func__); + return HDF_SUCCESS; +} + +int32_t AudioTestBindDaiLink(void) +{ + int32_t ret; + struct AudioCard *audioCard = NULL; + struct AudioConfigData *configData = NULL; + HDF_LOGI("%s: enter", __func__); + + ret = AudioBindDaiLink(audioCard, configData); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: AudioBindDaiLink fail ret = %d", __func__, ret); + } + + HDF_LOGI("%s: success", __func__); + return HDF_SUCCESS; +} + +int32_t AudioTestSocDeviceRegister(void) +{ + int32_t ret; + void *data = NULL; + enum AudioDeviceType deviceType; + struct HdfDeviceObject *device = NULL; + HDF_LOGI("%s: enter", __func__); + + ret = AudioSocDeviceRegister(device, data, deviceType); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: AudioSocDeviceRegister fail ret = %d", __func__, ret); + } + + HDF_LOGI("%s: success", __func__); + return HDF_SUCCESS; +} + +int32_t AudioTestSocRegisterDsp(void) +{ + int32_t ret; + struct HdfDeviceObject *device = NULL; + struct DaiData *data = NULL; + HDF_LOGI("%s: enter", __func__); + + ret = AudioSocRegisterDsp(device, data); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: AudioSocRegisterDsp fail ret = %d", __func__, ret); + } + + HDF_LOGI("%s: success", __func__); + return HDF_SUCCESS; +} + +int32_t AudioTestRegisterAccessory(void) +{ + int32_t ret; + struct HdfDeviceObject *device = NULL; + struct AccessoryData *data = NULL; + struct DaiData *daiData = NULL; + HDF_LOGI("%s: enter", __func__); + + ret = AudioRegisterAccessory(device, data, daiData); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: AudioRegisterAccessory fail ret = %d", __func__, ret); + } + + HDF_LOGI("%s: success", __func__); + return HDF_SUCCESS; +} + +int32_t AudioTestUpdateRegBits(void) +{ + int32_t codecRet; + int32_t accessoryRet; + int32_t value; + void *device = NULL; + struct AudioMixerControl *mixerControl = NULL; + HDF_LOGI("%s: enter", __func__); + + codecRet = AudioUpdateRegBits(AUDIO_CODEC_DEVICE, device, mixerControl, value); + accessoryRet = AudioUpdateRegBits(AUDIO_ACCESSORY_DEVICE, device, mixerControl, value); + if (codecRet != HDF_SUCCESS || accessoryRet != HDF_SUCCESS) { + HDF_LOGE("%s: AudioUpdateRegBits fail codecRet = %d, accessoryRet = %d", __func__, codecRet, accessoryRet); + } + + HDF_LOGI("%s: success", __func__); + return HDF_SUCCESS; +} + +int32_t AudioTestAiaoUpdateRegBits(void) +{ + uint32_t reg; + uint32_t mask; + uint32_t shift; + int32_t value; + int32_t ret; + struct CodecDevice *codec = NULL; + HDF_LOGI("%s: enter", __func__); + + ret = AudioAiaoUpdateRegBits(codec, reg, mask, shift, value); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: AudioAiaoUpdateRegBits fail ret = %d", __func__, ret); + } + + HDF_LOGI("%s: success", __func__); + return HDF_SUCCESS; +} + +int32_t AudioTestKcontrolGetCodec(void) +{ + struct CodecDevice *codecDevice = NULL; + const struct AudioKcontrol *kcontrol = NULL; + HDF_LOGI("%s: enter", __func__); + + codecDevice = AudioKcontrolGetCodec(kcontrol); + if (codecDevice == NULL) { + HDF_LOGE("%s: AudioKcontrolGetCodec fail!", __func__); + } + + HDF_LOGI("%s: success", __func__); + return HDF_SUCCESS; +} + +int32_t AudioTestAddControls(void) +{ + struct AudioCard *audioCard = NULL; + const struct AudioKcontrol *controls = NULL; + int32_t controlMaxNum = 0; + int32_t ret; + HDF_LOGI("%s: enter", __func__); + + ret = AudioAddControls(audioCard, controls, controlMaxNum); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: AudioAddControls fail ret = %d", __func__, ret); + } + + HDF_LOGI("%s: success", __func__); + return HDF_SUCCESS; +} + +int32_t AudioTestAddControl(void) +{ + struct AudioCard *audioCard = NULL; + const struct AudioKcontrol *control = NULL; + struct AudioKcontrol *audioKcontrol = NULL; + HDF_LOGI("%s: enter", __func__); + + audioKcontrol = AudioAddControl(audioCard, control); + if (audioKcontrol == NULL) { + HDF_LOGE("%s: AudioAddControl fail!", __func__); + } + + HDF_LOGI("%s: success", __func__); + return HDF_SUCCESS; +} + +int32_t AudioTestDeviceReadReg(void) +{ + int32_t codecRet; + int32_t acccessoryRet; + uint32_t reg = 0; + struct CodecDevice *codec = NULL; + struct AccessoryDevice *accessory = NULL; + HDF_LOGI("%s: enter", __func__); + + codecRet = AudioCodecDeviceReadReg(codec, reg); + acccessoryRet = AudioAccessoryDeviceReadReg(accessory, reg); + if (codecRet != HDF_SUCCESS || acccessoryRet != HDF_SUCCESS) { + HDF_LOGE("%s: AudioDeviceReadReg fail codecRet = %d, acccessoryRet = %d", __func__, codecRet, acccessoryRet); + } + HDF_LOGI("%s: success", __func__); + return HDF_SUCCESS; +} + +int32_t AudioTestAiaoDeviceReadReg(void) +{ + int32_t ret; + uint32_t reg = 0; + struct CodecDevice *codec = NULL; + HDF_LOGI("%s: enter", __func__); + + ret = AudioAiaoDeviceReadReg(codec, reg); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: AudioAiaoDeviceReadReg fail ret = %d", __func__, ret); + } + + HDF_LOGI("%s: success", __func__); + return HDF_SUCCESS; +} + +int32_t AudioTestInfoCtrlSw(void) +{ + int32_t ret; + struct AudioKcontrol *kcontrol = NULL; + struct AudioCtrlElemInfo *elemInfo = NULL; + HDF_LOGI("%s: enter", __func__); + + ret = AudioInfoCtrlSw(kcontrol, elemInfo); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: AudioInfoCtrlSw fail ret = %d", __func__, ret); + } + + HDF_LOGI("%s: success", __func__); + return HDF_SUCCESS; +} + +int32_t AudioTestGetCtrlSw(void) +{ + int32_t ret; + struct AudioKcontrol *kcontrol = NULL; + struct AudioCtrlElemValue *elemValue = NULL; + HDF_LOGI("%s: enter", __func__); + + ret = AudioGetCtrlSw(kcontrol, elemValue); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: AudioGetCtrlSw fail ret = %d", __func__, ret); + } + + HDF_LOGI("%s: success", __func__); + return HDF_SUCCESS; +} + +int32_t AudioTestPutCtrlSw(void) +{ + int32_t ret; + struct AudioKcontrol *kcontrol = NULL; + struct AudioCtrlElemValue *elemValue = NULL; + HDF_LOGI("%s: enter", __func__); + + ret = AudioPutCtrlSw(kcontrol, elemValue); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: AudioPutCtrlSw fail ret = %d", __func__, ret); + } + + HDF_LOGI("%s: success", __func__); + return HDF_SUCCESS; +} + +int32_t AiaoTestGetCtrlSw(void) +{ + int32_t ret; + struct AudioKcontrol *kcontrol = NULL; + struct AudioCtrlElemValue *elemValue = NULL; + HDF_LOGI("%s: enter", __func__); + + ret = AiaoGetCtrlSw(kcontrol, elemValue); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: AiaoGetCtrlSw fail ret = %d", __func__, ret); + } + + HDF_LOGI("%s: success", __func__); + return HDF_SUCCESS; +} + +int32_t AiaoTestPutCtrlSw(void) +{ + int32_t ret; + struct AudioKcontrol *kcontrol = NULL; + struct AudioCtrlElemValue *elemValue = NULL; + HDF_LOGI("%s: enter", __func__); + + ret = AiaoPutCtrlSw(kcontrol, elemValue); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: AiaoPutCtrlSw fail ret = %d", __func__, ret); + } + + HDF_LOGI("%s: success", __func__); + return HDF_SUCCESS; +} diff --git a/test/unittest/model/audio/src/audio_host_test.c b/test/unittest/model/audio/src/audio_host_test.c new file mode 100755 index 000000000..e13ab8630 --- /dev/null +++ b/test/unittest/model/audio/src/audio_host_test.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2020-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_host_test.h" +#include "audio_host.h" + +#define HDF_LOG_TAG audio_host_test + +int32_t AudioKcontrolTestGetCodec(void) +{ + struct HdfDeviceObject *device = NULL; + struct AudioHost *audioHost = NULL; + HDF_LOGI("%s: enter", __func__); + + audioHost = AudioHostCreateAndBind(device); + if (audioHost != NULL) { + HDF_LOGE("%s: codecDevice is not NULL", __func__); + return HDF_FAILURE; + } + + HDF_LOGI("%s: success", __func__); + return HDF_SUCCESS; +} + +int32_t GetCardTestInstance(void) +{ + int i; + const char *audioServiceName[] = { + "codec_service_0", + "codec_service_1", + "dma_service_0", + "dai_service", + "audio_service_0", + "audio_service_1", + "render_service", + "capture_service", + "control_service", + }; + HDF_LOGI("%s: enter", __func__); + + for (i = 0; i < sizeof(audioServiceName) / sizeof(audioServiceName[0]); ++i) { + if (GetCardInstance(audioServiceName[i]) == NULL) { + HDF_LOGE("%s: get %s fail!", __func__, audioServiceName[i]); + } + } + + HDF_LOGI("%s: success", __func__); + return HDF_SUCCESS; +} + +int32_t AudioHostTestDestroy(void) +{ + struct AudioHost *host = NULL; + HDF_LOGI("%s: enter", __func__); + + AudioHostDestroy(host); + HDF_LOGI("%s: success", __func__); + return HDF_SUCCESS; +} diff --git a/test/unittest/model/audio/src/audio_parse_test.c b/test/unittest/model/audio/src/audio_parse_test.c new file mode 100755 index 000000000..7c1ce6f42 --- /dev/null +++ b/test/unittest/model/audio/src/audio_parse_test.c @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2020-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_parse_test.h" +#include "audio_parse.h" + +#define HDF_LOG_TAG audio_parse_test + +int32_t AudioFillTestConfigData(void) +{ + int32_t ret; + struct HdfDeviceObject *device = NULL; + struct AudioConfigData *configData = NULL; + HDF_LOGI("%s: enter", __func__); + + ret = AudioFillConfigData(device, configData); + if (ret == HDF_SUCCESS) { + HDF_LOGE("%s: AudioFillConfigData fail! ret = %d", __func__, ret); + return HDF_FAILURE; + } + + HDF_LOGI("%s: success", __func__); + return HDF_SUCCESS; +} diff --git a/test/unittest/model/audio/src/audio_sapm_test.c b/test/unittest/model/audio/src/audio_sapm_test.c new file mode 100755 index 000000000..0c54d2c08 --- /dev/null +++ b/test/unittest/model/audio/src/audio_sapm_test.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2020-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_test.h" +#include "audio_sapm.h" + +#define HDF_LOG_TAG audio_host_test + +int32_t AudioSapmTestNewComponents(void) +{ + struct AudioCard *audioCard = NULL; + struct AudioSapmComponent *component = NULL; + int32_t maxNum = 0; + int32_t ret; + HDF_LOGI("%s: enter", __func__); + + ret = AudioSapmNewComponents(audioCard, component, maxNum); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: audioCart or component is NULL", __func__); + } + + HDF_LOGI("%s: success", __func__); + return HDF_SUCCESS; +} + +int32_t AudioSapmTestAddRoutes(void) +{ + struct AudioCard *audioCard = NULL; + struct AudioSapmRoute *route = NULL; + int32_t routeMaxNum = 0; + int32_t ret; + HDF_LOGI("%s: enter", __func__); + + ret = AudioSapmAddRoutes(audioCard, route, routeMaxNum); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: audioCard or route is NULL", __func__); + } + + HDF_LOGI("%s: success", __func__); + return HDF_SUCCESS; +} + +int32_t AudioSapmTestNewControls(void) +{ + struct AudioCard *audioCard = NULL; + int32_t ret; + HDF_LOGI("%s: enter", __func__); + + ret = AudioSapmNewControls(audioCard); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: audioCard is NULL", __func__); + } + + HDF_LOGI("%s: success", __func__); + return HDF_SUCCESS; +} + +int32_t AudioSapmTestPowerComponents(void) +{ + struct AudioCard *audioCard = NULL; + int32_t ret; + HDF_LOGI("%s: enter", __func__); + + ret = AudioSapmPowerComponents(audioCard); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: audioCard is NULL", __func__); + } + + HDF_LOGI("%s: success", __func__); + return HDF_SUCCESS; +} + + +int32_t AudioSapmTestRefreshTime(void) +{ + bool bRefresh = true; + u64 time; + HDF_LOGI("%s: enter", __func__); + + time = AudioSapmRefreshTime(bRefresh); + if (time == 0) { + HDF_LOGE("%s: error", __func__); + } + + HDF_LOGI("%s: success", __func__); + return HDF_SUCCESS; +} + diff --git a/test/unittest/model/audio/src/audio_stream_dispatch_test.c b/test/unittest/model/audio/src/audio_stream_dispatch_test.c new file mode 100755 index 000000000..afd6d95c7 --- /dev/null +++ b/test/unittest/model/audio/src/audio_stream_dispatch_test.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2020-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_stream_dispatch_test.h" +#include "audio_stream_dispatch.h" + +#define HDF_LOG_TAG audio_host_test + +int32_t AudioControlDispatchTestStreamDispatch(void) +{ + struct HdfDeviceIoClient *client = NULL; + struct HdfSBuf *data = NULL; + struct HdfSBuf *reply = NULL; + int32_t cmdId = 0; + int32_t ret; + HDF_LOGI("%s: enter", __func__); + + ret = StreamDispatch(client, cmdId, data, reply); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: (client || cmdId || data ||reply) is NULL", __func__); + } + + HDF_LOGI("%s: success", __func__); + return HDF_SUCCESS; +} + +int32_t AudioControlDispatchTestStreamHostDestroy(void) +{ + struct StreamHost *host = NULL; + HDF_LOGI("%s: enter", __func__); + + StreamHostDestroy(host); + + HDF_LOGI("%s: success", __func__); + return HDF_SUCCESS; +} diff --git a/test/unittest/model/audio/src/hdf_audio_test.c b/test/unittest/model/audio/src/hdf_audio_test.c new file mode 100755 index 000000000..be95e0055 --- /dev/null +++ b/test/unittest/model/audio/src/hdf_audio_test.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2020-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 "hdf_log.h" +#include "hdf_audio_test.h" +#include "audio_host_test.h" +#include "audio_core_test.h" +#include "audio_parse_test.h" +#include "audio_sapm_test.h" +#include "audio_stream_dispatch_test.h" + +#define HDF_LOG_TAG hdf_audio_test + +// add test case entry +static HdfTestCaseList g_hdfAudioTestCaseList[] = { + {AUDIO_DRIVER_TESTGETCODEC, AudioKcontrolTestGetCodec}, + {AUDIO_DRIVER_TESTGETCARDINSTANCE, GetCardTestInstance}, + {AUDIO_DRIVER_TESTHOSTDESTROY, AudioHostTestDestroy}, + {AUDIO_DRIVER_TESTGETCCNFIGDATA, AudioFillTestConfigData}, + {AUDIO_DRIVER_TESTREGISTERDAI, AudioSocTestRegisterDai}, + {AUDIO_DRIVER_TESTREGISTERPLATFORM, AudioSocTestRegisterPlatform}, + {AUDIO_DRIVER_TESTREGISTERCODEC, AudioTestRegisterCodec}, + {AUDIO_DRIVER_TESTBINDDAILINK, AudioTestBindDaiLink}, + {AUDIO_DRIVER_TESTDEVICEREGISTER, AudioTestSocDeviceRegister}, + {AUDIO_DRIVER_TESTREGISTERDSP, AudioTestSocRegisterDsp}, + {AUDIO_DRIVER_TESTREGISTERACCESSORY, AudioTestRegisterAccessory}, + {AUDIO_DRIVER_TESTUPDATEREGBITS, AudioTestUpdateRegBits}, + {AUDIO_DRIVER_TESTAIAOUPDATEREGBITS, AudioTestAiaoUpdateRegBits}, + {AUDIO_DRIVER_TESTKCONTROLGETCODEC, AudioTestKcontrolGetCodec}, + {AUDIO_DRIVER_TESTADDCONTROLS, AudioTestAddControls}, + {AUDIO_DRIVER_TESTADDCONTROL, AudioTestAddControl}, + {AUDIO_DRIVER_TESTDEVICEREADREG, AudioTestDeviceReadReg}, + {AUDIO_DRIVER_TESTAIAODEVICEREADREG, AudioTestAiaoDeviceReadReg}, + {AUDIO_DRIVER_TESTINFOCTRLSW, AudioTestInfoCtrlSw}, + {AUDIO_DRIVER_TESTGETCTRLSW, AudioTestGetCtrlSw}, + {AUDIO_DRIVER_TESTPUTCTRLSW, AudioTestPutCtrlSw}, + {AUDIO_DRIVER_TESTAIAOGETCTRLSW, AiaoTestGetCtrlSw}, + {AUDIO_DRIVER_TESTAIAOPUTCTRLSW, AiaoTestPutCtrlSw}, + {AUDIO_DRIVER_TESTNEWCOMPONENT, AudioSapmTestNewComponents}, + {AUDIO_DRIVER_TESTADDROUTES, AudioSapmTestAddRoutes}, + {AUDIO_DRIVER_TESTNEWCONTROLS, AudioSapmTestNewControls}, + {AUDIO_DRIVER_TESTPOWERCOMPONET, AudioSapmTestPowerComponents}, + {AUDIO_DRIVER_TESTREFRESHTIME, AudioSapmTestRefreshTime}, + {AUDIO_DRIVER_TESTSTREAMDISPATCH, AudioControlDispatchTestStreamDispatch}, + {AUDIO_DRIVER_TESTSTREAMDESTORY, AudioControlDispatchTestStreamHostDestroy}, +}; + +int32_t HdfAudioEntry(HdfTestMsg *msg) +{ + int32_t result, i; + + if (msg == NULL) { + HDF_LOGE("%s is fail: HdfTestMsg is NULL!", __func__); + return HDF_SUCCESS; + } + + for (i = 0; i < sizeof(g_hdfAudioTestCaseList) / sizeof(g_hdfAudioTestCaseList[0]); ++i) { + if ((msg->subCmd == g_hdfAudioTestCaseList[i].subCmd) && (g_hdfAudioTestCaseList[i].testFunc != NULL)) { + result = g_hdfAudioTestCaseList[i].testFunc(); + HDF_LOGE("HdfTest:Audio test result[%s-%u]", ((result == 0) ? "pass" : "fail"), msg->subCmd); + msg->result = (result == 0) ? HDF_SUCCESS : HDF_FAILURE; + return HDF_SUCCESS; + } + } + return HDF_SUCCESS; +} -- Gitee From af9d7984ed7a18bb4232e67ba1b0ef4774b38c20 Mon Sep 17 00:00:00 2001 From: vb6174 Date: Fri, 9 Jul 2021 06:19:02 +0000 Subject: [PATCH 02/32] update model/audio/device/soc/src/dai.c. --- model/audio/device/soc/src/dai.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model/audio/device/soc/src/dai.c b/model/audio/device/soc/src/dai.c index 1c1c097d0..afdf81f65 100755 --- a/model/audio/device/soc/src/dai.c +++ b/model/audio/device/soc/src/dai.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. -- Gitee From 1407f8edeb8621e83bbebb557cf0c36b41c012f0 Mon Sep 17 00:00:00 2001 From: vb6174 Date: Fri, 9 Jul 2021 06:19:23 +0000 Subject: [PATCH 03/32] update model/audio/device/soc/src/dsp.c. --- model/audio/device/soc/src/dsp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model/audio/device/soc/src/dsp.c b/model/audio/device/soc/src/dsp.c index 87ca7a7b0..c15908b69 100755 --- a/model/audio/device/soc/src/dsp.c +++ b/model/audio/device/soc/src/dsp.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. -- Gitee From fdbbd65763d6845b34185bef95a8030893e84916 Mon Sep 17 00:00:00 2001 From: vb6174 Date: Fri, 9 Jul 2021 06:19:36 +0000 Subject: [PATCH 04/32] update model/audio/device/soc/src/platform.c. --- model/audio/device/soc/src/platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model/audio/device/soc/src/platform.c b/model/audio/device/soc/src/platform.c index 34ebb449a..1d9033f56 100755 --- a/model/audio/device/soc/src/platform.c +++ b/model/audio/device/soc/src/platform.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. -- Gitee From b530491048036440eb10d5149ec7825a483f2f54 Mon Sep 17 00:00:00 2001 From: vb6174 Date: Fri, 9 Jul 2021 06:19:53 +0000 Subject: [PATCH 05/32] update model/audio/device/soc/include/dai_adapter.h. --- model/audio/device/soc/include/dai_adapter.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model/audio/device/soc/include/dai_adapter.h b/model/audio/device/soc/include/dai_adapter.h index 002f6ac7e..d3d767f19 100755 --- a/model/audio/device/soc/include/dai_adapter.h +++ b/model/audio/device/soc/include/dai_adapter.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. -- Gitee From 6f51faff9624caf1897fb0bdcdd5fb18de56cf7c Mon Sep 17 00:00:00 2001 From: vb6174 Date: Fri, 9 Jul 2021 06:20:13 +0000 Subject: [PATCH 06/32] update model/audio/device/soc/include/dsp_adapter.h. --- model/audio/device/soc/include/dsp_adapter.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model/audio/device/soc/include/dsp_adapter.h b/model/audio/device/soc/include/dsp_adapter.h index e4c73aa56..9d58ef1ce 100755 --- a/model/audio/device/soc/include/dsp_adapter.h +++ b/model/audio/device/soc/include/dsp_adapter.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. -- Gitee From 4e60458c1fcc882d235501d8eaeb72fe4df4d590 Mon Sep 17 00:00:00 2001 From: vb6174 Date: Fri, 9 Jul 2021 06:20:38 +0000 Subject: [PATCH 07/32] update model/audio/device/soc/include/platform_adapter.h. --- model/audio/device/soc/include/platform_adapter.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model/audio/device/soc/include/platform_adapter.h b/model/audio/device/soc/include/platform_adapter.h index c24b9229b..4dc4fea0a 100755 --- a/model/audio/device/soc/include/platform_adapter.h +++ b/model/audio/device/soc/include/platform_adapter.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. -- Gitee From 3895a994ab1b5922d9073b6035d4516b54b3216a Mon Sep 17 00:00:00 2001 From: vb6174 Date: Fri, 9 Jul 2021 06:21:10 +0000 Subject: [PATCH 08/32] update model/audio/device/accessory/include/accessory_adapter.h. --- model/audio/device/accessory/include/accessory_adapter.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model/audio/device/accessory/include/accessory_adapter.h b/model/audio/device/accessory/include/accessory_adapter.h index b75da35d4..185bb7bc9 100755 --- a/model/audio/device/accessory/include/accessory_adapter.h +++ b/model/audio/device/accessory/include/accessory_adapter.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. -- Gitee From 3520074aee79f8caf1a1ba27a1941491c1653da4 Mon Sep 17 00:00:00 2001 From: vb6174 Date: Fri, 9 Jul 2021 06:21:28 +0000 Subject: [PATCH 09/32] update model/audio/device/accessory/src/accessory.c. --- model/audio/device/accessory/src/accessory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model/audio/device/accessory/src/accessory.c b/model/audio/device/accessory/src/accessory.c index 09ad410dd..bf2aaaf1f 100755 --- a/model/audio/device/accessory/src/accessory.c +++ b/model/audio/device/accessory/src/accessory.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. -- Gitee From 459deab9f35fb5c2aba8deb86fdfd86d66e9f4d2 Mon Sep 17 00:00:00 2001 From: vb6174 Date: Fri, 9 Jul 2021 06:21:43 +0000 Subject: [PATCH 10/32] update model/audio/device/codec/include/codec_adapter.h. --- model/audio/device/codec/include/codec_adapter.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model/audio/device/codec/include/codec_adapter.h b/model/audio/device/codec/include/codec_adapter.h index dd5fa502e..4547c4430 100755 --- a/model/audio/device/codec/include/codec_adapter.h +++ b/model/audio/device/codec/include/codec_adapter.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. -- Gitee From 05a28f85dc3c51dd0880cc777652c2860930e8eb Mon Sep 17 00:00:00 2001 From: vb6174 Date: Fri, 9 Jul 2021 06:22:04 +0000 Subject: [PATCH 11/32] update model/audio/device/codec/src/codec.c. --- model/audio/device/codec/src/codec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model/audio/device/codec/src/codec.c b/model/audio/device/codec/src/codec.c index 54216a79c..5293eda02 100755 --- a/model/audio/device/codec/src/codec.c +++ b/model/audio/device/codec/src/codec.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. -- Gitee From 60bbc941979d8acde257da0045c386f63d704335 Mon Sep 17 00:00:00 2001 From: vb6174 Date: Fri, 9 Jul 2021 06:22:30 +0000 Subject: [PATCH 12/32] update model/audio/core/include/audio_control.h. --- model/audio/core/include/audio_control.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model/audio/core/include/audio_control.h b/model/audio/core/include/audio_control.h index 8b2fab186..dc362462d 100755 --- a/model/audio/core/include/audio_control.h +++ b/model/audio/core/include/audio_control.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. -- Gitee From 88c3234e91c6a863b9afe71e7981726964fc0e71 Mon Sep 17 00:00:00 2001 From: vb6174 Date: Fri, 9 Jul 2021 06:22:55 +0000 Subject: [PATCH 13/32] update model/audio/core/include/audio_core.h. --- model/audio/core/include/audio_core.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model/audio/core/include/audio_core.h b/model/audio/core/include/audio_core.h index 03ac9ab57..601768326 100755 --- a/model/audio/core/include/audio_core.h +++ b/model/audio/core/include/audio_core.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. -- Gitee From c723f1e2f61aaa91057d02bd1c02420bd18aae9c Mon Sep 17 00:00:00 2001 From: vb6174 Date: Fri, 9 Jul 2021 06:23:08 +0000 Subject: [PATCH 14/32] update model/audio/core/include/audio_host.h. --- model/audio/core/include/audio_host.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model/audio/core/include/audio_host.h b/model/audio/core/include/audio_host.h index 2ab9e3c57..603cbdc2b 100755 --- a/model/audio/core/include/audio_host.h +++ b/model/audio/core/include/audio_host.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. -- Gitee From 8107851a656fc8b4ceece4d341fc013787692610 Mon Sep 17 00:00:00 2001 From: vb6174 Date: Fri, 9 Jul 2021 06:23:23 +0000 Subject: [PATCH 15/32] update model/audio/core/include/audio_parse.h. --- model/audio/core/include/audio_parse.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model/audio/core/include/audio_parse.h b/model/audio/core/include/audio_parse.h index e73e14c58..03c931289 100755 --- a/model/audio/core/include/audio_parse.h +++ b/model/audio/core/include/audio_parse.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. -- Gitee From 3286bdda502eac5db0f4bb5c8f0021aab24c92a8 Mon Sep 17 00:00:00 2001 From: vb6174 Date: Fri, 9 Jul 2021 06:23:35 +0000 Subject: [PATCH 16/32] update model/audio/core/include/codec_core.h. --- model/audio/core/include/codec_core.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model/audio/core/include/codec_core.h b/model/audio/core/include/codec_core.h index a19378104..ddb49a548 100755 --- a/model/audio/core/include/codec_core.h +++ b/model/audio/core/include/codec_core.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. -- Gitee From 4033bcefbe1fcb306eadcb5181237cf828d84979 Mon Sep 17 00:00:00 2001 From: vb6174 Date: Fri, 9 Jul 2021 06:23:50 +0000 Subject: [PATCH 17/32] update model/audio/core/test/unittest/common/audio_common_test.h. --- model/audio/core/test/unittest/common/audio_common_test.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model/audio/core/test/unittest/common/audio_common_test.h b/model/audio/core/test/unittest/common/audio_common_test.h index 6cdde973f..26881f098 100755 --- a/model/audio/core/test/unittest/common/audio_common_test.h +++ b/model/audio/core/test/unittest/common/audio_common_test.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. -- Gitee From fce456b9ceaccdca4313a9326f4b08bc9e55489c Mon Sep 17 00:00:00 2001 From: vb6174 Date: Fri, 9 Jul 2021 06:24:08 +0000 Subject: [PATCH 18/32] update model/audio/core/test/unittest/common/audio_core_test.cpp. --- model/audio/core/test/unittest/common/audio_core_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model/audio/core/test/unittest/common/audio_core_test.cpp b/model/audio/core/test/unittest/common/audio_core_test.cpp index 9c5c9d176..3ea44f759 100755 --- a/model/audio/core/test/unittest/common/audio_core_test.cpp +++ b/model/audio/core/test/unittest/common/audio_core_test.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. -- Gitee From 42e39e17dee9f8af5b212edf779105b5020412eb Mon Sep 17 00:00:00 2001 From: vb6174 Date: Fri, 9 Jul 2021 06:24:22 +0000 Subject: [PATCH 19/32] update model/audio/core/test/unittest/common/audio_host_test.cpp. --- model/audio/core/test/unittest/common/audio_host_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model/audio/core/test/unittest/common/audio_host_test.cpp b/model/audio/core/test/unittest/common/audio_host_test.cpp index 095b15480..52e23e8db 100755 --- a/model/audio/core/test/unittest/common/audio_host_test.cpp +++ b/model/audio/core/test/unittest/common/audio_host_test.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. -- Gitee From 7ffcb3163a4982cff366e2e3f92b3361212fa727 Mon Sep 17 00:00:00 2001 From: vb6174 Date: Fri, 9 Jul 2021 06:27:49 +0000 Subject: [PATCH 20/32] update model/audio/core/test/unittest/common/audio_parse_test.cpp. --- model/audio/core/test/unittest/common/audio_parse_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model/audio/core/test/unittest/common/audio_parse_test.cpp b/model/audio/core/test/unittest/common/audio_parse_test.cpp index 5e44e1839..560cebd5e 100755 --- a/model/audio/core/test/unittest/common/audio_parse_test.cpp +++ b/model/audio/core/test/unittest/common/audio_parse_test.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. -- Gitee From 3963189d702e56df67d3b96983d1e762676aab12 Mon Sep 17 00:00:00 2001 From: vb6174 Date: Fri, 9 Jul 2021 06:33:53 +0000 Subject: [PATCH 21/32] update model/audio/sapm/include/audio_sapm.h. --- model/audio/sapm/include/audio_sapm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model/audio/sapm/include/audio_sapm.h b/model/audio/sapm/include/audio_sapm.h index 71be01f08..c7a452206 100755 --- a/model/audio/sapm/include/audio_sapm.h +++ b/model/audio/sapm/include/audio_sapm.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. -- Gitee From d831ee5d89b2279ec09bee9c63351e805c927277 Mon Sep 17 00:00:00 2001 From: vb6174 Date: Fri, 9 Jul 2021 06:34:09 +0000 Subject: [PATCH 22/32] update model/audio/sapm/src/audio_sapm.c. --- model/audio/sapm/src/audio_sapm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model/audio/sapm/src/audio_sapm.c b/model/audio/sapm/src/audio_sapm.c index 201a3c777..34a01d03d 100755 --- a/model/audio/sapm/src/audio_sapm.c +++ b/model/audio/sapm/src/audio_sapm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. -- Gitee From 64b020b4fef8652a6f6c9ffc7da10c4f557a2bd5 Mon Sep 17 00:00:00 2001 From: vb6174 Date: Fri, 9 Jul 2021 06:34:52 +0000 Subject: [PATCH 23/32] update model/audio/sapm/test/unittest/common/audio_sapm_test.cpp. --- model/audio/sapm/test/unittest/common/audio_sapm_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model/audio/sapm/test/unittest/common/audio_sapm_test.cpp b/model/audio/sapm/test/unittest/common/audio_sapm_test.cpp index 9e49ea001..7d700a9da 100755 --- a/model/audio/sapm/test/unittest/common/audio_sapm_test.cpp +++ b/model/audio/sapm/test/unittest/common/audio_sapm_test.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. -- Gitee From 0a403e152f2c70e101ec86c70636e8706d6d664e Mon Sep 17 00:00:00 2001 From: vb6174 Date: Fri, 9 Jul 2021 06:35:18 +0000 Subject: [PATCH 24/32] update model/audio/dispatch/include/audio_control_dispatch.h. --- model/audio/dispatch/include/audio_control_dispatch.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model/audio/dispatch/include/audio_control_dispatch.h b/model/audio/dispatch/include/audio_control_dispatch.h index cbaaf488b..0420881ee 100755 --- a/model/audio/dispatch/include/audio_control_dispatch.h +++ b/model/audio/dispatch/include/audio_control_dispatch.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. -- Gitee From 40cbf3700ba10c9118dcbb050aff910639aaf693 Mon Sep 17 00:00:00 2001 From: vb6174 Date: Fri, 9 Jul 2021 06:35:32 +0000 Subject: [PATCH 25/32] update model/audio/dispatch/include/audio_stream_dispatch.h. --- model/audio/dispatch/include/audio_stream_dispatch.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model/audio/dispatch/include/audio_stream_dispatch.h b/model/audio/dispatch/include/audio_stream_dispatch.h index 105504476..4c72ddb04 100755 --- a/model/audio/dispatch/include/audio_stream_dispatch.h +++ b/model/audio/dispatch/include/audio_stream_dispatch.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. -- Gitee From 7d5c52ebe40c5bc3a98f66999b367141a1ca927a Mon Sep 17 00:00:00 2001 From: vb6174 Date: Fri, 9 Jul 2021 06:36:11 +0000 Subject: [PATCH 26/32] update model/audio/dispatch/src/audio_control_dispatch.c. --- model/audio/dispatch/src/audio_control_dispatch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model/audio/dispatch/src/audio_control_dispatch.c b/model/audio/dispatch/src/audio_control_dispatch.c index 0f264c553..bc5d5d269 100755 --- a/model/audio/dispatch/src/audio_control_dispatch.c +++ b/model/audio/dispatch/src/audio_control_dispatch.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. -- Gitee From e0a422aed778e313351c48170279fab57d34d829 Mon Sep 17 00:00:00 2001 From: vb6174 Date: Fri, 9 Jul 2021 06:36:25 +0000 Subject: [PATCH 27/32] update model/audio/dispatch/src/audio_stream_dispatch.c. --- model/audio/dispatch/src/audio_stream_dispatch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model/audio/dispatch/src/audio_stream_dispatch.c b/model/audio/dispatch/src/audio_stream_dispatch.c index 171fc5205..550e84940 100755 --- a/model/audio/dispatch/src/audio_stream_dispatch.c +++ b/model/audio/dispatch/src/audio_stream_dispatch.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. -- Gitee From c81f49fcddaa58f0e5a568f11c130667c2df004b Mon Sep 17 00:00:00 2001 From: vb6174 Date: Fri, 9 Jul 2021 06:36:52 +0000 Subject: [PATCH 28/32] update model/audio/dispatch/test/unittest/common/audio_stream_dispatch_test.cpp. --- .../test/unittest/common/audio_stream_dispatch_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model/audio/dispatch/test/unittest/common/audio_stream_dispatch_test.cpp b/model/audio/dispatch/test/unittest/common/audio_stream_dispatch_test.cpp index d1ddb68a3..33fd4422f 100755 --- a/model/audio/dispatch/test/unittest/common/audio_stream_dispatch_test.cpp +++ b/model/audio/dispatch/test/unittest/common/audio_stream_dispatch_test.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. -- Gitee From 3306a99c589b3fae671afba05b93e705f8710f29 Mon Sep 17 00:00:00 2001 From: vb6174 Date: Fri, 9 Jul 2021 06:41:18 +0000 Subject: [PATCH 29/32] update core/sec/include/hdf_sec.h. --- core/sec/include/hdf_sec.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/sec/include/hdf_sec.h b/core/sec/include/hdf_sec.h index 90e3fd738..481a694f5 100644 --- a/core/sec/include/hdf_sec.h +++ b/core/sec/include/hdf_sec.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. -- Gitee From 403e5fcfeb20b6b3c56843421333e18bb914ec04 Mon Sep 17 00:00:00 2001 From: vb6174 Date: Fri, 9 Jul 2021 06:41:56 +0000 Subject: [PATCH 30/32] update core/adapter/syscall/include/hdf_syscall_adapter.h. --- core/adapter/syscall/include/hdf_syscall_adapter.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/adapter/syscall/include/hdf_syscall_adapter.h b/core/adapter/syscall/include/hdf_syscall_adapter.h index cb83b3f98..cc42fc74c 100644 --- a/core/adapter/syscall/include/hdf_syscall_adapter.h +++ b/core/adapter/syscall/include/hdf_syscall_adapter.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. -- Gitee From a6853862330c3c379d00dc734953f271605101ea Mon Sep 17 00:00:00 2001 From: vb6174 Date: Fri, 9 Jul 2021 06:42:33 +0000 Subject: [PATCH 31/32] update core/adapter/syscall/src/hdf_devmgr_adapter.c. --- core/adapter/syscall/src/hdf_devmgr_adapter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/adapter/syscall/src/hdf_devmgr_adapter.c b/core/adapter/syscall/src/hdf_devmgr_adapter.c index 5a4e63e3a..b91a4e29e 100644 --- a/core/adapter/syscall/src/hdf_devmgr_adapter.c +++ b/core/adapter/syscall/src/hdf_devmgr_adapter.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. -- Gitee From fa1464c6a375b8cf733e7f309b5815dc1a214717 Mon Sep 17 00:00:00 2001 From: vb6174 Date: Fri, 9 Jul 2021 06:42:48 +0000 Subject: [PATCH 32/32] update core/adapter/syscall/src/hdf_syscall_adapter.c. --- core/adapter/syscall/src/hdf_syscall_adapter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/adapter/syscall/src/hdf_syscall_adapter.c b/core/adapter/syscall/src/hdf_syscall_adapter.c index 908022746..da3987efe 100644 --- a/core/adapter/syscall/src/hdf_syscall_adapter.c +++ b/core/adapter/syscall/src/hdf_syscall_adapter.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. -- Gitee