From c66bcb26ce869a066b5bd1cc1cd33360fb5f0a9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B0=A2=E4=BB=B2=E5=88=9D?= Date: Tue, 30 Apr 2024 11:24:23 +0800 Subject: [PATCH] I9KVZX HDF eDP Management Interfaces Implement MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 添加HDF框架eDP参数管理接口 2. 添加适配器实现接口 3. 添加HDF eDP部件配置 Signed-off-by: 谢仲初 --- adapter/khdf/linux/platform/edp/Kconfig | 0 adapter/khdf/linux/platform/edp/Makefile | 21 ++ .../linux/platform/edp/edp_adapter_impl.c | 276 ++++++++++++++++ adapter/khdf/linux/platform/edp/edp_adaptor.h | 21 ++ .../khdf/linux/platform/edp/edp_linux_def.h | 52 +++ adapter/khdf/linux/platform/edp/edp_rk3568.c | 213 +++++++++++++ adapter/khdf/linux/platform/edp/edp_rk3568.h | 229 ++++++++++++++ .../model/display/driver/panel/lcd_edp.c | 253 +++++++++++++++ .../model/display/driver/panel/lcd_edp.h | 47 +++ .../support/platform/include/edp/edp_core.h | 173 ++++++++++ .../platform/include/edp/edp_dispatch.h | 39 +++ .../support/platform/include/edp/edp_if.h | 286 +++++++++++++++++ framework/support/platform/src/edp/edp_core.c | 295 ++++++++++++++++++ .../support/platform/src/edp/edp_dispatch.c | 159 ++++++++++ framework/support/platform/src/edp/edp_if.c | 99 ++++++ 15 files changed, 2163 insertions(+) create mode 100644 adapter/khdf/linux/platform/edp/Kconfig create mode 100644 adapter/khdf/linux/platform/edp/Makefile create mode 100644 adapter/khdf/linux/platform/edp/edp_adapter_impl.c create mode 100644 adapter/khdf/linux/platform/edp/edp_adaptor.h create mode 100644 adapter/khdf/linux/platform/edp/edp_linux_def.h create mode 100644 adapter/khdf/linux/platform/edp/edp_rk3568.c create mode 100644 adapter/khdf/linux/platform/edp/edp_rk3568.h create mode 100644 framework/model/display/driver/panel/lcd_edp.c create mode 100644 framework/model/display/driver/panel/lcd_edp.h create mode 100644 framework/support/platform/include/edp/edp_core.h create mode 100644 framework/support/platform/include/edp/edp_dispatch.h create mode 100644 framework/support/platform/include/edp/edp_if.h create mode 100644 framework/support/platform/src/edp/edp_core.c create mode 100644 framework/support/platform/src/edp/edp_dispatch.c create mode 100644 framework/support/platform/src/edp/edp_if.c diff --git a/adapter/khdf/linux/platform/edp/Kconfig b/adapter/khdf/linux/platform/edp/Kconfig new file mode 100644 index 000000000..e69de29bb diff --git a/adapter/khdf/linux/platform/edp/Makefile b/adapter/khdf/linux/platform/edp/Makefile new file mode 100644 index 000000000..240d303a3 --- /dev/null +++ b/adapter/khdf/linux/platform/edp/Makefile @@ -0,0 +1,21 @@ +# +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. +# +# This software is licensed under the terms of the GNU General Public +# License version 2, as published by the Free Software Foundation, and +# may be copied, distributed, and modified under those terms. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# +include drivers/hdf/khdf/platform/platform.mk + +obj-$(CONFIG_DRIVERS_HDF_PLATFORM_EDP) += \ + $(HDF_PLATFORM_FRAMEWORKS_ROOT)/src/edp/edp_core.o \ + $(HDF_PLATFORM_FRAMEWORKS_ROOT)/src/edp/edp_if.o \ + $(HDF_PLATFORM_FRAMEWORKS_ROOT)/src/edp/edp_dispatch.o \ + edp_adapter_impl.o \ + edp_rk3568.o \ No newline at end of file diff --git a/adapter/khdf/linux/platform/edp/edp_adapter_impl.c b/adapter/khdf/linux/platform/edp/edp_adapter_impl.c new file mode 100644 index 000000000..a35646c99 --- /dev/null +++ b/adapter/khdf/linux/platform/edp/edp_adapter_impl.c @@ -0,0 +1,276 @@ + +#include "osal.h" +#include "platform_if.h" +#include "platform_device.h" +#include "hdf_device_desc.h" +#include "device_resource_if.h" + +#include "edp_core.h" +#include "edp_if.h" +#include "edp_dispatch.h" +#include "securec.h" + +#include "edp_linux_def.h" + +#define HDF_LOG_TAG edp_adapter_impl + +static inline hdf_edp_adapter_t * EdpAdapterPrivToEdpData(struct EdpCntlr *cntlr) +{ + if (cntlr == NULL) { + return NULL; + } + return (hdf_edp_adapter_t *)cntlr->priv; +} + +static int32_t EdpAdapterDeepColorSet(struct EdpCntlr *cntlr, enum EdpColorDepth color) +{ + int32_t ret = -1; + hdf_edp_adapter_t * edpAdapterData = EdpAdapterPrivToEdpData(cntlr); + if (edpAdapterData == NULL) { + HDF_LOGE("%s, edp priv data is null", __func__); + return ret; + } + + ret = LinuxEdpDeepColorSet(edpAdapterData, color); + return ret; +} + +static int32_t EdpAdapterDeepColorGet(struct EdpCntlr* cntlr, enum EdpColorDepth *color) +{ + int32_t ret = -1; + hdf_edp_adapter_t * edpAdapterData = EdpAdapterPrivToEdpData(cntlr); + if (edpAdapterData == NULL) { + HDF_LOGE("%s, edp priv data is null", __func__); + return ret; + } + + uint32_t colorGet = 0; + ret = LinuxEdpDeepColorGet(edpAdapterData, &colorGet); + if (HDF_SUCCESS != ret) { + HDF_LOGE("%s, LinuxEdpDeepColorGet failed %d", __func__, ret); + return ret; + } + + *color = colorGet; + return ret; +} + +static int32_t EdpAdapterAvmuteSet(struct EdpCntlr *cntlr, bool enable) +{ + (void)cntlr; + (void)enable; + return HDF_SUCCESS; +} + +static int32_t EdpAdapterSetVideoAttribute(struct EdpCntlr *cntlr, const struct EdpVideoAttr *attr) +{ + int32_t ret = -1; + if (cntlr == NULL || attr == NULL) { + HDF_LOGE("%s, invalid cntlr data\n", __func__); + return ret; + } + hdf_edp_adapter_t * edpAdapterData = EdpAdapterPrivToEdpData(cntlr); + if (edpAdapterData == NULL) { + HDF_LOGE("%s, edp priv data is null", __func__); + return ret; + } + + ret = LinuxEdpSetVideoAttribute(edpAdapterData, (void *)attr); + + return ret; +} + +static int32_t EdpAdapterSetAudioAttribute(struct EdpCntlr * cntlr, const struct EdpAudioAttr *attr) +{ + (void)cntlr; + (void)attr; + return HDF_SUCCESS; +} + +static int32_t EdpAdapterRegisterHpdCallbackFunc(struct EdpCntlr *cntlr, struct EdpHpdCallbackInfo *callback) +{ + (void)cntlr; + (void)callback; + return HDF_SUCCESS; +} + +static int32_t EdpAdapterUnregisterHpdCallbackFunc(struct EdpCntlr *cntlr) +{ + (void)cntlr; + return HDF_SUCCESS; +} + + +static struct EdpCntlrOps g_edpCntlrOps = { + .open = NULL, + .close = NULL, + .start = NULL, + .stop = NULL, + .avmuteSet = EdpAdapterAvmuteSet, + .deepColorSet = EdpAdapterDeepColorSet, + .deepColorGet = EdpAdapterDeepColorGet, + .setVideoAttribute = EdpAdapterSetVideoAttribute, + .setAudioAttribute = EdpAdapterSetAudioAttribute, + .registerHpdCallbackFunc = EdpAdapterRegisterHpdCallbackFunc, + .unregisterHpdCallbackFunc = EdpAdapterUnregisterHpdCallbackFunc, +}; + +static int32_t EdpAdapterOpsInit(struct EdpCntlr *cntlr) +{ + if (cntlr == NULL) { + return HDF_ERR_INVALID_OBJECT; + } + cntlr->ops = &g_edpCntlrOps; + + return HDF_SUCCESS; +} + +static int32_t EdpAdapterOpsDeInit(struct EdpCntlr *cntlr) +{ + (void)cntlr; + return HDF_SUCCESS; +} + +static int32_t EdpAdapterInit(struct EdpCntlr *cntlr) +{ + int32_t ret = -1; + if (cntlr == NULL) { + HDF_LOGE("%s, device handle is null", __func__); + return ret; + } + hdf_edp_adapter_t *edpAdapterData = NULL; + + edpAdapterData = (hdf_edp_adapter_t *)OsalMemCalloc(sizeof(hdf_edp_adapter_t)); + if (NULL == edpAdapterData) { + HDF_LOGE("Alloc mem for adapter data failed\n"); + return ret; + } + + ret = LinuxEdpAdapterInit(edpAdapterData); + if (HDF_SUCCESS != ret) { + OsalMemFree(edpAdapterData); + return ret; + } + cntlr->priv = (void *)edpAdapterData; + + enum EdpColorDepth color; + EdpAdapterDeepColorGet(cntlr, &color); + HDF_LOGI("Finished, color: %d!!\n", color); + EdpAdapterDeepColorSet(cntlr, EDP_COLOR_DEPTH_8BIT); + return ret; +} + +static int32_t EdpAdapterDeInit(struct EdpCntlr *cntlr) +{ + int32_t ret = -1; + hdf_edp_adapter_t * edpAdapterData = EdpAdapterPrivToEdpData(cntlr); + + if (NULL == edpAdapterData) + { + HDF_LOGE("edp adapter data is NULL\n"); + return ret; + } + + LinuxEdpAdapterDeInit(edpAdapterData); + OsalMemFree(edpAdapterData); + + ret = 0; + return ret; +} + +static int32_t EdpCntlrInit(struct EdpCntlr *cntlr, struct HdfDeviceObject *obj) +{ + int32_t ret; + uint32_t num = 0; + struct DeviceResourceIface *iface = NULL; + + if (cntlr == NULL) { + return HDF_ERR_INVALID_OBJECT; + } + + if (obj == NULL) { + HDF_LOGE("EdpCntlrInit: no HdfDeviceObject attached!"); + return HDF_ERR_INVALID_OBJECT; + } + iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); + if (iface == NULL || iface->GetUint32 == NULL) { + HDF_LOGE("HdfPwmInit: iface or GetUint32 is null!"); + return HDF_FAILURE; + } + // if (iface->GetUint32(obj->property, "num", &num, 0) != HDF_SUCCESS) { + // HDF_LOGE("HdfPwmInit: read num fail!"); + // return HDF_FAILURE; + // } + + cntlr->hdfDevObj = obj; + cntlr->num = num; + cntlr->device.number = (int32_t)cntlr->deviceIndex; + cntlr->device.hdfDev = cntlr->hdfDevObj; + ret = EdpAdapterInit(cntlr); + return ret; +} + +static void EdpCntlrDeinit(struct EdpCntlr *cntlr) +{ + if (cntlr != NULL) { + EdpAdapterDeInit(cntlr); + // EdpCntlrFreeDev(cntlr); + (void)OsalMutexDestroy(&cntlr->mutex); + } +} + +static int32_t HdfEdpBind(struct HdfDeviceObject *obj) +{ + (void)obj; + return HDF_SUCCESS; +} + +static int32_t HdfEdpInit(struct HdfDeviceObject *obj) +{ + int32_t ret = -1; + struct EdpCntlr *cntlr = NULL; + + HDF_LOGI("%s: entry", __func__); + if (obj == NULL) { + HDF_LOGE("%s: obj is null", __func__); + return HDF_ERR_INVALID_OBJECT; + } + + cntlr = (struct EdpCntlr *)OsalMemCalloc(sizeof(struct EdpCntlr)); + if (cntlr == NULL) { + HDF_LOGE("%s: OsalMemCalloc cntlr error", __func__); + return HDF_ERR_MALLOC_FAIL; + } + + ret = OsalMutexInit(&cntlr->mutex); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: mutex init fail!", __func__); + return ret; + } + + cntlr->state = EDP_CNTLR_STATE_NONE; + cntlr->service.Dispatch = &EdpIoDispatch; + // ret = EdpCntlrDeviceAdd(obj, cntlr); + ret = EdpCntlrInit(cntlr, obj); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: error probe, ret is %d", __func__, ret); + OsalMemFree(cntlr); + } + + return ret; +} + +static void HdfEdpRelease(struct HdfDeviceObject *obj) +{ + HDF_LOGI("%s: entry", __func__); +} + +struct HdfDriverEntry g_hdfEdpEntry = { + .moduleVersion = 1, + .moduleName = "HDF_EDP", + .Bind = HdfEdpBind, + .Init = HdfEdpInit, + .Release = HdfEdpRelease, +}; + +HDF_INIT(g_hdfEdpEntry); \ No newline at end of file diff --git a/adapter/khdf/linux/platform/edp/edp_adaptor.h b/adapter/khdf/linux/platform/edp/edp_adaptor.h new file mode 100644 index 000000000..17dde26c9 --- /dev/null +++ b/adapter/khdf/linux/platform/edp/edp_adaptor.h @@ -0,0 +1,21 @@ +#ifndef __EDP_ADAPTER_H__ +#define __EDP_ADAPTER_H__ + +#include "edp_core.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +void EdpInit(struct EdpCntlr *cntlr); +void EdpDeinit(struct EdpCntlr *cntlr); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + +#endif //__EDP_ADAPTER_H__ \ No newline at end of file diff --git a/adapter/khdf/linux/platform/edp/edp_linux_def.h b/adapter/khdf/linux/platform/edp/edp_linux_def.h new file mode 100644 index 000000000..7ee0d1503 --- /dev/null +++ b/adapter/khdf/linux/platform/edp/edp_linux_def.h @@ -0,0 +1,52 @@ +#ifndef __EDP_LINUX_DEF_H__ +#define __EDP_LINUX_DEF_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +typedef struct hdf_edp_adapter_s { + struct platform_device *platDev; + struct device *dev; + struct device_node *node; + struct drm_device *drmDev; + struct drm_bridge *drmBridge; + struct drm_panel *drmPanel; + struct drm_connector *connector; + void *driverData; +}hdf_edp_adapter_t; + +int32_t LinuxEdpAdapterInit(hdf_edp_adapter_t *); +void LinuxEdpAdapterDeInit(hdf_edp_adapter_t *); +int32_t LinuxEdpDeepColorSet(hdf_edp_adapter_t*, uint32_t); +int32_t LinuxEdpDeepColorGet(hdf_edp_adapter_t*, uint32_t*); +int32_t LinuxEdpSetVideoAttribute(hdf_edp_adapter_t*, void*); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + +#endif //__EDP_LINUX_DEF_H__ \ No newline at end of file diff --git a/adapter/khdf/linux/platform/edp/edp_rk3568.c b/adapter/khdf/linux/platform/edp/edp_rk3568.c new file mode 100644 index 000000000..165ca41ed --- /dev/null +++ b/adapter/khdf/linux/platform/edp/edp_rk3568.c @@ -0,0 +1,213 @@ +#include "hdf_base.h" +#include "hdf_log.h" + +#include "edp_linux_def.h" +#include "edp_rk3568.h" + +#define HDF_LOG_TAG edp_rk3568_hdf + +static int32_t EdpBpcToColorDepth(uint32_t bpc, uint32_t*color) +{ + int32_t ret = -1; + switch(bpc) { + case COLOR_6: + *color = 6; + break; + case COLOR_8: + *color = 8; + break; + case COLOR_10: + *color = 10; + break; + case COLOR_12: + *color = 12; + break; + default: + return ret; + } + ret = 0; + return ret; +} + +static int32_t EdpColorDepthToBpc(uint32_t *bpc, uint32_t color ) +{ + int32_t ret = -1; + switch(color) { + case 6: + *bpc = COLOR_6; + break; + case 8: + *bpc = COLOR_8; + break; + case 10: + *bpc = COLOR_10; + break; + case 12: + *bpc = COLOR_12; + break; + default: + return ret; + } + ret = 0; + return ret; +} + +int32_t LinuxEdpAdapterInit(hdf_edp_adapter_t *edpAdapterData) +{ + int32_t ret = -1; + if (NULL == edpAdapterData) { + HDF_LOGE("%s null adapter get\n", __func__); + return ret; + } + struct drm_device *edpDrmDev = NULL; + struct drm_panel *edpDrmPanel = NULL; + struct drm_bridge *edpDrmBridge = NULL; + struct device * edpDev = NULL; + struct drm_mode_config *drmConfig = NULL; + struct EdpCntlrOps *ops = NULL; + struct device_node *edpNode = NULL; + struct platform_device *platDev = NULL; + struct device_node *dispDevNode = NULL; + void * privData = NULL; + // edpNode = of_find_compatible_node(edpNode, NULL, "rockchip,rk3568-edp"); + edpNode = of_find_node_by_path("/edp@fe0c0000"); + if (NULL == edpNode) { + HDF_LOGE("find edp dt node failed\n"); + return ret; + } + HDF_LOGI("find edp dt node!!dev is: %x\n", edpNode->fwnode.dev); + platDev = of_find_device_by_node(edpNode); + if (NULL == platDev) { + HDF_LOGE("find platform device of edp dt node failed\n"); + return ret; + } + privData = platform_get_drvdata(platDev); + edpDrmBridge = &((struct rockchip_dp_device *)privData)->adp->bridge; + HDF_LOGI("of_find_device_by_node: %x, dev: %x, priv: %x, bridge: %x\n", platDev, platDev->dev.of_node, privData, edpDrmBridge); + + dispDevNode = of_find_node_by_path("/display-subsystem"); + if (NULL == dispDevNode) { + HDF_LOGE("find display-subsystem node failed\n"); + return ret; + } + HDF_LOGI("of_find_node_by_path/display-subsystem: %x\n", dispDevNode); + HDF_LOGI("drm_of_find_panel_or_bridge(%x, %d, %d, %x, %x)!!\n", edpNode, 1, -1, &edpDrmPanel, &edpDrmBridge); + ret = drm_of_find_panel_or_bridge(edpNode, 1, -1, &edpDrmPanel, &edpDrmBridge); + if (HDF_SUCCESS != ret) { + HDF_LOGE("drm_of_find_panel_or_bridge failed: %d\n", ret); + return ret; + } + + HDF_LOGI("drm_of_find_panel_or_bridge returned: panel: %x bridge: %x!!\n", edpDrmPanel, edpDrmBridge); + if (!edpDrmBridge) { + edpDrmBridge = &((struct rockchip_dp_device *)privData)->adp->bridge; + HDF_LOGI("of_find_device_by_node: %x, dev: %x, priv: %x, bridge: %x\n", platDev, platDev->dev.of_node, privData, edpDrmBridge); + #if 0 + // edpDrmBridge = of_drm_find_bridge(dispDevNode); + // if (!edpDrmBridge) { + ret = drm_of_find_panel_or_bridge(dispDevNode, 1, -1, NULL, &edpDrmBridge); + if (HDF_SUCCESS != ret) { + HDF_LOGE("of_drm_find_bridge failed %d\n", ret); + return ret; + } + #endif + } + + HDF_LOGI("drm_of_find_panel_or_bridge returned: panel: %x bridge: %x!!\n", edpDrmPanel, edpDrmBridge); + if (edpDrmBridge) { + edpDrmDev = edpDrmBridge->dev; + edpAdapterData->connector = drm_panel_bridge_connector(edpDrmBridge); + HDF_LOGI("drm_panel_bridge_connector %x!!\n", edpAdapterData->connector); + if (!edpAdapterData->connector) { + HDF_LOGE("drm_panel_bridge_connector failed\n"); + return -1; + } + } + if (edpDrmDev) { + HDF_LOGI("Assigning adapter edpDrmDev data %x!!\n", edpDrmDev); + edpDev = edpDrmDev->dev; + } + + edpAdapterData->platDev = platDev; + edpAdapterData->dev = edpDev; + edpAdapterData->node = edpNode; + edpAdapterData->drmDev = edpDrmDev; + edpAdapterData->drmPanel = edpDrmPanel; + edpAdapterData->drmBridge = edpDrmBridge; + edpAdapterData->connector = &((struct rockchip_dp_device *)privData)->adp->connector; + // edpAdapterData->driverData = dev_get_drvdata(edpDev); + + ret = HDF_SUCCESS; + return ret; +} + +void LinuxEdpAdapterDeInit(hdf_edp_adapter_t *edpAdapterData) +{ + if (edpAdapterData == NULL) { + HDF_LOGE("%s, edp priv data is null", __func__); + return; + } +} + +int32_t LinuxEdpDeepColorSet(hdf_edp_adapter_t* edpAdapterData, uint32_t color) +{ + int32_t ret = -1; + if (edpAdapterData == NULL) { + HDF_LOGE("%s, edp priv data is null", __func__); + return ret; + } + struct drm_display_mode mode; + struct drm_display_mode adjustedMode; + struct drm_display_info *info = &edpAdapterData->connector->display_info; + struct drm_atomic_state oldState; + HDF_LOGI("drm_mode_copy() %x!!\n", edpAdapterData->connector); + drm_mode_copy(&mode, &edpAdapterData->connector->encoder->crtc->state->mode); + drm_mode_copy(&adjustedMode, &mode); + + //modify video bpc to setup color depth by edp driver + ret = EdpColorDepthToBpc(&info->bpc, color); + if (ret != 0) { + return ret; + } + + HDF_LOGI("drm_atomic_bridge_chain_disable()!!\n"); + // drm_atomic_bridge_chain_disable(e000dpAdapterData->drmBridge, &oldState); + HDF_LOGI("drm_bridge_chain_mode_set()!!\n"); + drm_bridge_chain_mode_set(edpAdapterData->drmBridge, &mode, &adjustedMode); + HDF_LOGI("drm_atomic_bridge_chain_enable()!!\n"); + // drm_atomic_bridge_chain_enable(edpAdapterData->drmBridge, &oldState); + + ret = HDF_SUCCESS; + return ret; +} + +int32_t LinuxEdpDeepColorGet(hdf_edp_adapter_t* edpAdapterData, uint32_t* color) +{ + int32_t ret = -1; + if (edpAdapterData == NULL || color == NULL) { + HDF_LOGE("%s, edp priv data is null", __func__); + return ret; + } + struct rockchip_dp_device *drvData = platform_get_drvdata(edpAdapterData->platDev); + + if (drvData == NULL) { + + } + HDF_LOGI("drm_display_info %x!!\n", edpAdapterData->connector); + drvData->plat_data.get_modes(&drvData->plat_data, edpAdapterData->connector); + struct drm_display_info *info = &edpAdapterData->connector->display_info; + ret = EdpBpcToColorDepth(info->bpc, color); + + return ret; +} + +int32_t LinuxEdpSetVideoAttribute(hdf_edp_adapter_t *edpAdapterData, void *videoAttr) +{ + int32_t ret = -1; + if (edpAdapterData == NULL || videoAttr == NULL) { + HDF_LOGE("%s, null parameters got", __func__); + return ret; + } + + return ret; +} \ No newline at end of file diff --git a/adapter/khdf/linux/platform/edp/edp_rk3568.h b/adapter/khdf/linux/platform/edp/edp_rk3568.h new file mode 100644 index 000000000..72858835f --- /dev/null +++ b/adapter/khdf/linux/platform/edp/edp_rk3568.h @@ -0,0 +1,229 @@ +#ifndef __EDP_RK3568_H__ +#define __EDP_RK3568_H__ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +struct analogix_dp_plat_data; +struct rockchip_drm_sub_dev; + +enum link_lane_count_type { + LANE_COUNT1 = 1, + LANE_COUNT2 = 2, + LANE_COUNT4 = 4 +}; + +enum link_training_state { + START, + CLOCK_RECOVERY, + EQUALIZER_TRAINING, + FINISHED, + FAILED +}; + +enum voltage_swing_level { + VOLTAGE_LEVEL_0, + VOLTAGE_LEVEL_1, + VOLTAGE_LEVEL_2, + VOLTAGE_LEVEL_3, +}; + +enum pre_emphasis_level { + PRE_EMPHASIS_LEVEL_0, + PRE_EMPHASIS_LEVEL_1, + PRE_EMPHASIS_LEVEL_2, + PRE_EMPHASIS_LEVEL_3, +}; + +enum pattern_set { + PRBS7, + D10_2, + TRAINING_PTN1, + TRAINING_PTN2, + TRAINING_PTN3, + DP_NONE +}; + +enum color_space { + COLOR_RGB, + COLOR_YCBCR422, + COLOR_YCBCR444 +}; + +enum color_depth { + COLOR_6, + COLOR_8, + COLOR_10, + COLOR_12 +}; + +enum color_coefficient { + COLOR_YCBCR601, + COLOR_YCBCR709 +}; + +enum dynamic_range { + VESA, + CEA +}; + +enum pll_status { + PLL_UNLOCKED, + PLL_LOCKED +}; + +enum clock_recovery_m_value_type { + CALCULATED_M, + REGISTER_M +}; + +enum video_timing_recognition_type { + VIDEO_TIMING_FROM_CAPTURE, + VIDEO_TIMING_FROM_REGISTER +}; + +enum analog_power_block { + AUX_BLOCK, + CH0_BLOCK, + CH1_BLOCK, + CH2_BLOCK, + CH3_BLOCK, + ANALOG_TOTAL, + POWER_ALL +}; + +enum dp_irq_type { + DP_IRQ_TYPE_HP_CABLE_IN = BIT(0), + DP_IRQ_TYPE_HP_CABLE_OUT = BIT(1), + DP_IRQ_TYPE_HP_CHANGE = BIT(2), + DP_IRQ_TYPE_UNKNOWN = BIT(3), +}; + +struct rockchip_drm_sub_dev { + struct list_head list; + struct drm_connector *connector; + struct device_node *of_node; + void (*loader_protect)(struct drm_encoder *encoder, bool on); + void (*oob_hotplug_event)(struct drm_connector *connector); +}; + +struct video_info { + char *name; + struct drm_display_mode mode; + + bool h_sync_polarity; + bool v_sync_polarity; + bool interlaced; + + enum color_space color_space; + enum dynamic_range dynamic_range; + enum color_coefficient ycbcr_coeff; + enum color_depth color_depth; + + int max_link_rate; + enum link_lane_count_type max_lane_count; + + bool video_bist_enable; +}; + +struct link_train { + int eq_loop; + int cr_loop[4]; + + u8 link_rate; + u8 lane_count; + u8 training_lane[4]; + bool ssc; + bool enhanced_framing; + + enum link_training_state lt_state; +}; + +struct analogix_dp_device { + struct drm_encoder *encoder; + struct device *dev; + struct drm_device *drm_dev; + struct drm_connector connector; + struct drm_bridge bridge; + struct drm_dp_aux aux; + struct clk_bulk_data *clks; + int nr_clks; + unsigned int irq; + void __iomem *reg_base; + + struct video_info video_info; + struct link_train link_train; + struct phy *phy; + bool phy_enabled; + int dpms_mode; + struct gpio_desc *hpd_gpiod; + bool force_hpd; + bool fast_train_enable; + bool psr_supported; + + struct mutex panel_lock; + bool panel_is_prepared; + + struct analogix_dp_plat_data *plat_data; +}; + +struct rockchip_grf_reg_field { + unsigned int reg; + unsigned int lsb; + unsigned int msb; + bool valid; +}; + +/** + * struct rockchip_dp_chip_data - splite the grf setting of kind of chips + * @lcdc_sel: grf register field of lcdc_sel + * @spdif_sel: grf register field of spdif_sel + * @i2s_sel: grf register field of i2s_sel + * @edp_mode: grf register field of edp_mode + * @chip_type: specific chip type + * @ssc: check if SSC is supported by source + * @audio: check if audio is supported by source + * @split_mode: check if split mode is supported + */ +struct rockchip_dp_chip_data { + const struct rockchip_grf_reg_field lcdc_sel; + const struct rockchip_grf_reg_field spdif_sel; + const struct rockchip_grf_reg_field i2s_sel; + const struct rockchip_grf_reg_field edp_mode; + u32 chip_type; + bool ssc; + bool audio; + bool split_mode; +}; + +struct rockchip_dp_device { + struct drm_device *drm_dev; + struct device *dev; + struct drm_encoder encoder; + struct drm_bridge *bridge; + struct drm_display_mode mode; + + struct regmap *grf; + struct reset_control *rst; + struct reset_control *apb_reset; + + struct platform_device *audio_pdev; + const struct rockchip_dp_chip_data *data; + int id; + + struct analogix_dp_device *adp; + struct analogix_dp_plat_data plat_data; + struct rockchip_drm_sub_dev sub_dev; +}; + + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + +#endif //__EDP_RK3568_H__ \ No newline at end of file diff --git a/framework/model/display/driver/panel/lcd_edp.c b/framework/model/display/driver/panel/lcd_edp.c new file mode 100644 index 000000000..1f4d128ab --- /dev/null +++ b/framework/model/display/driver/panel/lcd_edp.c @@ -0,0 +1,253 @@ +/* + * Copyright (c) 2022 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 "lcd_edp.h" +#include "gpio_if.h" +#include "hdf_bl.h" +#include "hdf_disp.h" +#include "osal.h" + +struct panel_edp_dev *g_edp_panel_dev = NULL; + +static struct panel_edp_dev *ToPanelSimpleDev(const struct PanelData *panel) +{ + return (struct panel_edp_dev *)panel->object->priv; +} + +static int32_t PanelSimpleRegulatorEnable(void) +{ + int32_t err; + if (g_edp_panel_dev == NULL) { + return -1; + } + err = regulator_enable(g_edp_panel_dev->supply); + if (err < 0) { + HDF_LOGE("regulator_enable failed"); + return err; + } + return 0; +} +static int32_t PanelSimpleRegulatorDIsable(void) +{ + if (g_edp_panel_dev == NULL) { + return -1; + } + regulator_disable(g_edp_panel_dev->supply); + return 0; +} + +static int32_t PanelOn(struct PanelData *panel) +{ + struct panel_edp_dev *panel_dev = NULL; + + panel_dev = ToPanelSimpleDev(panel); + if (panel_dev->hw_delay.enable_delay) { + OsalMSleep(panel_dev->hw_delay.enable_delay); + } + return HDF_SUCCESS; +} + +static int32_t PanelOff(struct PanelData *panel) +{ + struct panel_edp_dev *panel_dev = NULL; + + panel_dev = ToPanelSimpleDev(panel); + if (panel_dev->hw_delay.disable_delay) { + OsalMSleep(panel_dev->hw_delay.disable_delay); + } + return HDF_SUCCESS; +} + +static int32_t PanelPrepare(struct PanelData *panel) +{ + int32_t ret; + struct panel_edp_dev *panel_dev = NULL; + + panel_dev = ToPanelSimpleDev(panel); + ret = regulator_enable(panel_dev->supply); + if (ret < 0) { + HDF_LOGE("failed to enable supply: %d\n", ret); + return ret; + } + gpiod_set_value_cansleep(panel_dev->enable_gpio, 1); + + if (panel_dev->hw_delay.reset_delay > 0) { + OsalMSleep(panel_dev->hw_delay.reset_delay); + } + + gpiod_set_value_cansleep(panel_dev->reset_gpio, 1); + + if (panel_dev->hw_delay.reset_delay > 0) { + OsalMSleep(panel_dev->hw_delay.reset_delay); + } + + gpiod_set_value_cansleep(panel_dev->reset_gpio, 0); + + if (panel_dev->hw_delay.prepare_delay > 0) { + OsalMSleep(panel_dev->hw_delay.prepare_delay); + } + + if (panel_dev->hw_delay.init_delay > 0) { + OsalMSleep(panel_dev->hw_delay.init_delay); + } + + return HDF_SUCCESS; +} + +static int32_t PanelUnprepare(struct PanelData *panel) +{ + int32_t ret; + struct panel_edp_dev *panel_dev = NULL; + + panel_dev = ToPanelSimpleDev(panel); + + gpiod_set_value_cansleep(panel_dev->reset_gpio, 1); + gpiod_set_value_cansleep(panel_dev->enable_gpio, 0); + regulator_disable(panel_dev->supply); + + if (panel_dev->hw_delay.unprepare_delay) { + OsalMSleep(panel_dev->hw_delay.unprepare_delay); + } + + return HDF_SUCCESS; +} + +static int32_t PanelRegulatorEnable(struct PanelData *panel) +{ + int32_t ret; + struct panel_edp_dev *panel_dev = NULL; + + panel_dev = ToPanelSimpleDev(panel); + ret = regulator_enable(panel_dev->supply); + if (ret < 0) { + HDF_LOGE("failed to enable supply: %d\n", ret); + return ret; + } + + return HDF_SUCCESS; +} + +static int32_t PanelInit(struct PanelData *panel) +{ + return 0; +} + +#define BLK_PWM_INDEX 2 +#define PWM_MAX_PERIOD 40000 +/* backlight setting */ +#define MIN_LEVEL 0 +#define MAX_LEVEL 255 +#define DEFAULT_LEVEL 127 + +static struct PanelInfo g_panelInfo = { + .width = 1920, /* width */ + .height = 1080, /* height */ + .hbp = 48, /* horizontal back porch */ + .hfp = 88, /* horizontal front porch */ + .hsw = 44, /* horizontal sync width */ + .vbp = 36, /* vertical back porch */ + .vfp = 4, /* vertical front porch */ + .vsw = 5, /* vertical sync width */ + .clockFreq = 70600000, /* clock */ + .pWidth = 298, /* physical width */ + .pHeight = 168, /* physical height */ + .connectorType = DRM_MODE_CONNECTOR_DPI, /* DRM_MODE_CONNECTOR_DPI=17 */ + .blk = { BLK_PWM, MIN_LEVEL, MAX_LEVEL, DEFAULT_LEVEL }, +}; + +static void PanelResInit(struct panel_edp_dev *panel_dev) +{ + panel_dev->panel.info = &g_panelInfo; + panel_dev->panel.init = PanelInit; + panel_dev->panel.on = PanelOn; + panel_dev->panel.off = PanelOff; + panel_dev->panel.prepare = PanelPrepare; + panel_dev->panel.unprepare = PanelUnprepare; + panel_dev->panel.panelRegulatorEnable = PanelRegulatorEnable; + panel_dev->panel.prepared = false; + panel_dev->panel.priv = panel_dev->edpDev; + panel_dev->hw_delay.disable_delay = 50; /* 50:disable_delay time */ + panel_dev->hw_delay.enable_delay = 120; /* 120:enable_delay */ + panel_dev->hw_delay.init_delay = 20; /* 20:init_delay */ + panel_dev->hw_delay.prepare_delay = 20; /* 20:prepare_delay */ + panel_dev->hw_delay.reset_delay = 20; /* 20:reset_delay */ + panel_dev->hw_delay.unprepare_delay = 20; /* 20:unprepare_delay */ +} + +static int32_t PanelEDPEntryInit(struct HdfDeviceObject *object) +{ + HDF_LOGW("%s Performing", __func__); + struct device_node *panelNode = NULL; + struct panel_edp_dev *panel_dev = NULL; + struct platform_device *edp_platformDev; + + panel_dev = (struct panel_edp_dev *)OsalMemCalloc(sizeof(struct panel_edp_dev)); + if (panel_dev == NULL) { + HDF_LOGE("%s panel_dev malloc fail", __func__); + return HDF_FAILURE; + } + g_edp_panel_dev = panel_dev; + panelNode = of_find_compatible_node(NULL, NULL, "simple-panel"); + if (panelNode == NULL) { + HDF_LOGE("%s of_find_compatible_node fail", __func__); + goto FAIL; + } + + edp_platformDev = of_find_device_by_node(panelNode); + panel_dev->edpDev = &edp_platformDev->dev; + if (panel_dev->edpDev == NULL) { + HDF_LOGE("%s of_find_device_by_node fail", __func__); + goto FAIL; + } + + panel_dev->supply = devm_regulator_get(panel_dev->edpDev, "power"); + if (panel_dev->supply == NULL) { + HDF_LOGE("%s Get regulator fail", __func__); + goto FAIL; + } + + panel_dev->enable_gpio = devm_gpiod_get_optional(panel_dev->edpDev, "enable", GPIOD_ASIS); + if (IS_ERR(panel_dev->enable_gpio)) { + HDF_LOGE("%s get enable_gpio fail", __func__); + goto FAIL; + } + panel_dev->hpd_gpio = devm_gpiod_get_optional(panel_dev->edpDev, "hpd", GPIOD_IN); + if (IS_ERR(panel_dev->hpd_gpio)) { + HDF_LOGE("%s get hpd_gpio fail", __func__); + goto FAIL; + } + panel_dev->reset_gpio = devm_gpiod_get_optional(panel_dev->edpDev, "reset", GPIOD_ASIS); + if (IS_ERR(panel_dev->reset_gpio)) { + HDF_LOGE("%s get reset_gpio fail", __func__); + goto FAIL; + } + + PanelResInit(panel_dev); + panel_dev->panel.object = object; + object->priv = panel_dev; + + panel_dev->panel.panelType = LCD_EDP; + + if (RegisterPanel(&panel_dev->panel) != HDF_SUCCESS) { + HDF_LOGE("%s RegisterPanel fail", __func__); + goto FAIL; + } + HDF_LOGI("%s success", __func__); + return HDF_SUCCESS; +FAIL: + OsalMemFree(panel_dev); + return HDF_FAILURE; +} + +struct HdfDriverEntry PanelEDPDevEntry = { + .moduleVersion = 1, + .moduleName = "LCD_EDP", + .Init = PanelEDPEntryInit, +}; + +HDF_INIT(PanelEDPDevEntry); diff --git a/framework/model/display/driver/panel/lcd_edp.h b/framework/model/display/driver/panel/lcd_edp.h new file mode 100644 index 000000000..020faa1a0 --- /dev/null +++ b/framework/model/display/driver/panel/lcd_edp.h @@ -0,0 +1,47 @@ +#ifndef __LCD_EDP_H__ +#define __LCD_EDP_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "hdf_disp.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +struct panel_edp_hw_delay { + uint32_t prepare_delay; + uint32_t hpd_absent_delay; + uint32_t enable_delay; + uint32_t disable_delay; + uint32_t unprepare_delay; + uint32_t reset_delay; + uint32_t init_delay; +}; + +struct panel_edp_dev { + bool power_invert; + struct PanelData panel; + struct device *edpDev; + struct regulator *supply; + struct gpio_desc *enable_gpio; + struct gpio_desc *reset_gpio; + struct gpio_desc *hpd_gpio; + struct panel_edp_hw_delay hw_delay; +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif + +#endif //__LCD_EDP_H__ \ No newline at end of file diff --git a/framework/support/platform/include/edp/edp_core.h b/framework/support/platform/include/edp/edp_core.h new file mode 100644 index 000000000..d9581a96f --- /dev/null +++ b/framework/support/platform/include/edp/edp_core.h @@ -0,0 +1,173 @@ +#ifndef __EDP_CORE_H__ +#define __EDP_CORE_H__ + +// HDF common header files +#include "hdf_base.h" +#include "hdf_device_desc.h" +#include "osal_mutex.h" +#include "platform_core.h" +#include "osal_spinlock.h" + +#include "edp_if.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +#define EDP_ONE_BYTE_MARK 0xFF +#define EDP_ONE_BYTE_SHIFT 8 +#define EDP_TWO_BYTES_SHIFT 16 +#define EDP_SERVICE_NAME_LEN 32 +#define EDP_NAME_BUF_LEN 32 + +struct EdpPhyCfg { + uint32_t pixelClk; + uint32_t tmdsClk; /* TMDS clock, KHz */ + enum EdpColorDepth deepColor; /* deep color(color depth) */ + enum EdpColorSpace colorSpace; +}; + +struct EdpCntlr; + +union EdpCap { + uint32_t data; +}; + +enum EdpAudioFormat { + AFMT_I2S = 0, + AFMT_SPDIF = 1, + AFMT_UNUSED, +}; + +struct EdpAudioInfo +{ + enum EdpAudioFormat format; + int32_t sampleRate; + int32_t channels; + int32_t sampleWidth; +}; + +struct EdpCntlrCap { + union EdpCap baseCap; + uint32_t maxTmdsClock; + uint32_t defTmdsClock; /* unit: MHz */ + uint32_t maxFrlRate; + uint32_t videoTiming; + uint32_t quantization; + uint32_t colorSpace; + uint32_t colorimetry; + uint32_t audioIfType; + uint32_t audioBitDepth; + uint32_t audioSampleRate; + uint32_t audioChannels; + uint32_t hdrColorimetry; + uint32_t hdrUserMode; +}; + +struct EdpAudioConfigInfo { + bool enable; + bool downSample; + uint32_t tmdsClock; + uint32_t pixelRepeat; + enum EdpSampleRate sampleRate; +}; + +struct EdpCntlrOps { + int32_t (*open)(struct EdpCntlr *cntlr); + int32_t (*close)(struct EdpCntlr *cntlr); + int32_t (*start)(struct EdpCntlr *cntlr); + int32_t (*stop)(struct EdpCntlr *cntlr); + int32_t (*avmuteSet)(struct EdpCntlr *cntlr, bool enable); + int32_t (*deepColorSet)(struct EdpCntlr *cntlr, enum EdpColorDepth color); + int32_t (*deepColorGet)(struct EdpCntlr *cntlr, enum EdpColorDepth *color); + int32_t (*setVideoAttribute)(struct EdpCntlr *cntlr, const struct EdpVideoAttr *attr); + int32_t (*getVideoAttribute)(struct EdpCntlr *cntlr, struct EdpVideoAttr *attr); + int32_t (*setAudioAttribute)(struct EdpCntlr *cntlr, const struct EdpAudioAttr *attr); + int32_t (*getAudioAttribute)(struct EdpCntlr *cntlr, struct EdpAudioAttr *attr); + int32_t (*registerHpdCallbackFunc)(struct EdpCntlr *cntlr, struct EdpHpdCallbackInfo *callback); + int32_t (*unregisterHpdCallbackFunc)(struct EdpCntlr *cntlr); +}; + +enum EdpCntlrState { + EDP_CNTLR_STATE_NONE = 0, + EDP_CNTLR_STATE_OPEN = (1 << 0), + EDP_CNTLR_STATE_START = (1 << 1), + EDP_CNTLR_STATE_STOP = (1 << 2), + EDP_CNTLR_STATE_CLOSE = (1 << 3), +}; + +enum EdpEventType { + EDP_EVENT_TYPE_NONE, +}; + +struct EdpDevice { + struct EdpCntlr *cntlr; + void *priv; +}; + +struct EdpAttr { + struct EdpAudioInfo audioAttr; + struct EdpVideoAttr videoAttr; +}; + +struct EdpCntlr { + struct IDeviceIoService service; + struct HdfDeviceObject *hdfDevObj; + struct PlatformDevice device; + struct OsalMutex mutex; + struct EdpCntlrCap cap; + struct EdpAttr attr; + struct EdpCntlrOps *ops; + uint32_t num; + uint32_t deviceIndex; + enum EdpCntlrState state; /* cntlr state. */ + OsalSpinlock lock; + void *priv; +}; + +static inline void EdpCntlrLock(struct EdpCntlr *cntlr) +{ + if (cntlr != NULL) { + (void)OsalMutexLock(&cntlr->mutex); + } +} + +static inline void EdpCntlrUnlock(struct EdpCntlr *cntlr) +{ + if (cntlr != NULL) { + (void)OsalMutexUnlock(&cntlr->mutex); + } +} + +static inline struct EdpCntlr *EdpCntlrGetByBusNum(uint16_t num) +{ + struct PlatformDevice *device = PlatformManagerGetDeviceByNumber(PlatformManagerGet(PLATFORM_MODULE_EDP), num); + + if (device == NULL) { + return NULL; + } + return CONTAINER_OF(device, struct EdpCntlr, device); +} + +DevHandle EdpCntlrOpen(uint16_t busNum); +void EdpCntlrClose(struct EdpCntlr *cntlr); +int32_t EdpCntlrDeepColorGet(struct EdpCntlr *cntlr, enum EdpColorDepth *color); +int32_t EdpCntlrDeepColorSet(struct EdpCntlr *cntlr, enum EdpColorDepth color); +int32_t EdpCntlrSetVideoAttribute(struct EdpCntlr *cntlr, const struct EdpVideoAttr * attr); +int32_t EdpCntlrGetVideoAttribute(struct EdpCntlr *cntlr, struct EdpVideoAttr * attr); +int32_t EdpCntlrSetAudioAttribute(struct EdpCntlr * cntlr, const struct EdpAudioAttr *attr); +int32_t EdpCntlrAvmuteSet(struct EdpCntlr *cntlr, bool enable); +int32_t EdpEventHandle(struct EdpCntlr *cntlr, enum EdpEventType event, void *data); +int32_t EdpCntlrDeviceAdd(struct HdfDeviceObject *obj, struct EdpCntlr *cntlr); +int32_t EdpCntlrRegisterHpdCallbackFunc(struct EdpCntlr *cntlr, struct EdpHpdCallbackInfo *callback); +int32_t EdpCntlrUnregisterHpdCallbackFunc(struct EdpCntlr *cntlr); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + +#endif //__EDP_CORE_H__ \ No newline at end of file diff --git a/framework/support/platform/include/edp/edp_dispatch.h b/framework/support/platform/include/edp/edp_dispatch.h new file mode 100644 index 000000000..8e7bba11b --- /dev/null +++ b/framework/support/platform/include/edp/edp_dispatch.h @@ -0,0 +1,39 @@ +#ifndef __EDP_DISPATCH_H__ +#define __EDP_DISPATCH_H__ + +#include "hdf_base.h" +#include "devsvc_manager_clnt.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +enum EdpIoCmd { + EDP_CMD_OPEN, + EDP_CMD_CLOSE, + EDP_CMD_START, + EDP_CMD_STOP, + EDP_CMD_AVMUTE_SET, + EDP_CMD_DEEP_COLOR_SET, + EDP_CMD_DEEP_COLOR_GET, + EDP_CMD_VIDEO_ATTR_SET, + EDP_CMD_AUDIO_ATTR_SET, + EDP_CMD_HDR_ATTR_SET, + EDP_CMD_READ_SINK_EDID, + EDP_CMD_INFOFRAME_SET, + EDP_CMD_INFOFRAME_GET, + EDP_CMD_REGISTER_HPD_CALLBACK_FUNC, + EDP_CMD_UNREGISTER_HPD_CALLBACK_FUNC, + EDP_CMD_BUTT, +}; + +int32_t EdpIoDispatch(struct HdfDeviceIoClient *client, int cmdId, struct HdfSBuf *data, struct HdfSBuf *reply); +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + +#endif //__EDP_DISPATCH_H__ \ No newline at end of file diff --git a/framework/support/platform/include/edp/edp_if.h b/framework/support/platform/include/edp/edp_if.h new file mode 100644 index 000000000..f19a3204c --- /dev/null +++ b/framework/support/platform/include/edp/edp_if.h @@ -0,0 +1,286 @@ +#ifndef __EDP_IF_H__ +#define __EDP_IF_H__ + +#include "platform_if.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +enum EdpColorDepth { + EDP_COLOR_DEPTH_NONE = 0, + EDP_COLOR_DEPTH_6BIT = 6, + EDP_COLOR_DEPTH_8BIT = 8, + EDP_COLOR_DEPTH_10BIT = 10, + EDP_COLOR_DEPTH_12BIT = 12, + EDP_COLOR_DEPTH_INVALID, +}; + +enum EdpColorSpace { + EDP_COLOR_SPACE_RGB = 0, + EDP_COLOR_SPACE_YCBCR422 = 1, + EDP_COLOR_SPACE_YCBCR444 = 2, +}; + +enum EdpColorCoefficient { + EDP_COLOR_COEFF_YCBCR601, + EDP_COLOR_COEFF_YCBCR709, +}; + +enum EdpDynamicRange { + EDP_DYNAMIC_RANGE_VESA, + EDP_DYNAMIC_RANGE_CEA, +}; + +enum EdpVideoTimingRecognitionType { + EDP_VIDEO_TIMING_FROM_CAPTURE, + EDP_VIDEO_TIMING_FROM_REGISTER +}; + +// enum EdpAnalogPowerBlock { +// AUX_BLOCK, +// CH0_BLOCK, +// CH1_BLOCK, +// CH2_BLOCK, +// CH3_BLOCK, +// ANALOG_TOTAL, +// POWER_ALL +// }; + +/** + * extracted from drm + * enum dp_colorimetry - drm DP Colorimetry formats + * + * This enum is used to indicate DP VSC SDP Colorimetry formats. + * It is based on DP 1.4 spec [Table 2-117: VSC SDP Payload for DB16 through + * DB18] and a name of enum member follows DRM_MODE_COLORIMETRY definition. + * + * @DP_COLORIMETRY_DEFAULT: sRGB (IEC 61966-2-1) or + * ITU-R BT.601 colorimetry format + * @DP_COLORIMETRY_RGB_WIDE_FIXED: RGB wide gamut fixed point colorimetry format + * @DP_COLORIMETRY_BT709_YCC: ITU-R BT.709 colorimetry format + * @DP_COLORIMETRY_RGB_WIDE_FLOAT: RGB wide gamut floating point + * (scRGB (IEC 61966-2-2)) colorimetry format + * @DP_COLORIMETRY_XVYCC_601: xvYCC601 colorimetry format + * @DP_COLORIMETRY_OPRGB: OpRGB colorimetry format + * @DP_COLORIMETRY_XVYCC_709: xvYCC709 colorimetry format + * @DP_COLORIMETRY_DCI_P3_RGB: DCI-P3 (SMPTE RP 431-2) colorimetry format + * @DP_COLORIMETRY_SYCC_601: sYCC601 colorimetry format + * @DP_COLORIMETRY_RGB_CUSTOM: RGB Custom Color Profile colorimetry format + * @DP_COLORIMETRY_OPYCC_601: opYCC601 colorimetry format + * @DP_COLORIMETRY_BT2020_RGB: ITU-R BT.2020 R' G' B' colorimetry format + * @DP_COLORIMETRY_BT2020_CYCC: ITU-R BT.2020 Y'c C'bc C'rc colorimetry format + * @DP_COLORIMETRY_BT2020_YCC: ITU-R BT.2020 Y' C'b C'r colorimetry format + */ +enum EdpColorimetry { + EDP_COLORIMETRY_DEFAULT = 0, + EDP_COLORIMETRY_RGB_WIDE_FIXED = 0x1, + EDP_COLORIMETRY_BT709_YCC = 0x1, + EDP_COLORIMETRY_RGB_WIDE_FLOAT = 0x2, + EDP_COLORIMETRY_XVYCC_601 = 0x2, + EDP_COLORIMETRY_OPRGB = 0x3, + EDP_COLORIMETRY_XVYCC_709 = 0x3, + EDP_COLORIMETRY_DCI_P3_RGB = 0x4, + EDP_COLORIMETRY_SYCC_601 = 0x4, + EDP_COLORIMETRY_RGB_CUSTOM = 0x5, + EDP_COLORIMETRY_OPYCC_601 = 0x5, + EDP_COLORIMETRY_BT2020_RGB = 0x6, + EDP_COLORIMETRY_BT2020_CYCC = 0x6, + EDP_COLORIMETRY_BT2020_YCC = 0x7, +}; + +enum EdpSampleRate { + EDP_SAMPLE_RATE_UNKNOWN, + EDP_SAMPLE_RATE_8K = 8000, + EDP_SAMPLE_RATE_11K = 11025, + EDP_SAMPLE_RATE_12K = 12000, + EDP_SAMPLE_RATE_16K = 16000, + EDP_SAMPLE_RATE_22K = 22050, + EDP_SAMPLE_RATE_24K = 24000, + EDP_SAMPLE_RATE_32K = 32000, + EDP_SAMPLE_RATE_44K = 44100, + EDP_SAMPLE_RATE_48K = 48000, + EDP_SAMPLE_RATE_88K = 88200, + EDP_SAMPLE_RATE_96K = 96000, + EDP_SAMPLE_RATE_176K = 176400, + EDP_SAMPLE_RATE_192K = 192000, + EDP_SAMPLE_RATE_768K = 768000, + EDP_SAMPLE_RATE_BUTT, +}; + +enum EdpAudioBitDepth { + EDP_AUDIO_BIT_DEPTH_UNKNOWN, + EDP_AUDIO_BIT_DEPTH_8 = 8, + EDP_AUDIO_BIT_DEPTH_16 = 16, + EDP_AUDIO_BIT_DEPTH_18 = 18, + EDP_AUDIO_BIT_DEPTH_20 = 20, + EDP_AUDIO_BIT_DEPTH_24 = 24, + EDP_AUDIO_BIT_DEPTH_32 = 32, + EDP_AUDIO_BIT_DEPTH_BUTT, +}; + +enum EdpAudioCodingType { + EDP_AUDIO_CODING_TYPE_STREAM = 0, + EDP_AUDIO_CODING_TYPE_LPCM = 1, + EDP_AUDIO_CODING_TYPE_AC3 = 2, + EDP_AUDIO_CODING_TYPE_MPEG1 = 3, + EDP_AUDIO_CODING_TYPE_MP3 = 4, + EDP_AUDIO_CODING_TYPE_MPEG2 = 5, + EDP_AUDIO_CODING_TYPE_AAC_LC = 6, + EDP_AUDIO_CODING_TYPE_DTS = 7, + EDP_AUDIO_CODING_TYPE_ATRAC = 8, + EDP_AUDIO_CODING_TYPE_OBA = 9, + EDP_AUDIO_CODING_TYPE_EAC3 = 10, + EDP_AUDIO_CODING_TYPE_DTS_HD = 11, + EDP_AUDIO_CODING_TYPE_MLP = 12, + EDP_AUDIO_CODING_TYPE_DST = 13, + EDP_AUDIO_CODING_TYPE_WMA_PRO = 14, + EDP_AUDIO_CODING_TYPE_CXT = 15, +}; + +enum EdpVideoTiming { + EDP_VIDEO_TIMING_NONE = 0, + EDP_VIDEO_TIMING_640X480P60 = 1, + EDP_VIDEO_TIMING_720X480P60 = 2, + EDP_VIDEO_TIMING_1280X720P60 = 3, + EDP_VIDEO_TIMING_1920X1080P60 = 4, +}; + +enum EdpAudioInterfaceType { + EDP_AUDIO_IF_TYPE_I2S = 0, /* Inter-IC Sound */ + EDP_AUDIO_IF_TYPE_SPDIF = 1, /* Sony/Philips Digital Interface */ + EDP_AUDIO_IF_TYPE_OTHER, +}; + +enum EdpAudioFormatChannel { + EDP_AUDIO_FORMAT_CHANNEL_2 = 2, + EDP_AUDIO_FORMAT_CHANNEL_3, + EDP_AUDIO_FORMAT_CHANNEL_4, + EDP_AUDIO_FORMAT_CHANNEL_5, + EDP_AUDIO_FORMAT_CHANNEL_6, + EDP_AUDIO_FORMAT_CHANNEL_7, + EDP_AUDIO_FORMAT_CHANNEL_8, + EDP_AUDIO_FORMAT_CHANNEL_BUTT, +}; + +struct EdpVideoAttr { + uint32_t tmdsClock; /* unit: KHz */ + uint32_t pixelClock; /* unit: KHz */ + uint32_t pixelRepeat; + enum EdpColorSpace colorSpace; + enum EdpColorimetry colorimetry; + enum EdpColorDepth colorDepth; + enum EdpVideoTiming timing; +}; + +struct EdpAudioAttr { + enum EdpAudioCodingType codingType; + enum EdpAudioInterfaceType ifType; + enum EdpAudioBitDepth bitDepth; + enum EdpSampleRate sampleRate; + bool downSample; + enum EdpAudioFormatChannel channels; +}; + +struct EdpHpdCallbackInfo { + void *data; + void (*callbackFunc)(void *data, bool hdp); +}; + +/** + * @brief EdpOpen open Edp device by bus number + * + * @param busNum bus number of the target screen + * @return DevHandle handler of the target, return NULL while error occurs + */ +DevHandle EdpOpen(uint16_t busNum); + +/** + * @brief release handle resources both in user space and kernel space, + * It just release resources which is related to the handle. + * + * @param handle device handler + */ +void EdpClose(DevHandle handle); + +/** + * @brief EdpAvmuteSet mute edp audio output + * + * @param handle device handler of target + * @param enable true for muting output/false for turning on output + * @return int32_t 0 for sucess, other for error + */ +int32_t EdpAvmuteSet(DevHandle handle, bool enable); + +/** + * @brief EdpDeepColorSet setup deep color for screen + * + * @param handle device handler + * @param color color data for setup + * @return int32_t 0 for success, other for error + */ +int32_t EdpDeepColorSet(DevHandle handle, enum EdpColorDepth color); + +/** + * @brief EdpDeepColorGet fetch deep color current data from hdf service + * + * @param handle device handler + * @param color memory for get the data from hdf service + * @return int32_t 0 for sucess, other for error + */ +int32_t EdpDeepColorGet(DevHandle handle, enum EdpColorDepth *color); + +/** + * @brief EdpSetVideoAttribute setup video attribute + * + * @param handle device handler + * @param attr video attribute details for setup + * @return int32_t 0 for sucess, other for error + */ +int32_t EdpSetVideoAttribute(DevHandle handle, struct EdpVideoAttr *attr); + +/** + * @brief EdpSetAudioAttribute setup audio attribute + * + * @param handle device handler + * @param attr audio attribute details for setup + * @return int32_t 0 for sucess, other for error + */ +int32_t EdpSetAudioAttribute(DevHandle handle, struct EdpAudioAttr *attr); + +/** + * @brief EdpRegisterHpdCallbackFunc register callback for hpd event? + * + * I don't think this api can be implement in user space + * @param handle + * @param callback + * @return int32_t + */ +int32_t EdpRegisterHpdCallbackFunc(DevHandle handle, struct EdpHpdCallbackInfo *callback); + +/** + * @brief EdpUnregisterHpdCallbackFunc remove the registered hpd event cb in kernel space + * This is a terrible interface to perform this operation from a user request + * @param handle device handler + * @return int32_t + */ +int32_t EdpUnregisterHpdCallbackFunc(DevHandle handle); + +/** + * @brief EdpBackLightSetup setup backlight for Edp device + * + * @param handle device handler for backlight setup + * @param value backlight value to setup + * @return int32_t + */ +int32_t EdpBackLightSetup(DevHandle handle, int32_t value); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + +#endif //__EDP_IF_H__ \ No newline at end of file diff --git a/framework/support/platform/src/edp/edp_core.c b/framework/support/platform/src/edp/edp_core.c new file mode 100644 index 000000000..9b86eab00 --- /dev/null +++ b/framework/support/platform/src/edp/edp_core.c @@ -0,0 +1,295 @@ +#include "device_resource_if.h" +#include "hdf_log.h" +#include "osal_mem.h" +#include "osal_time.h" +#include "securec.h" + +#include "edp_if.h" +#include "edp_core.h" + +#define HDF_LOG_TAG edp_core + +static void *EdpCntlrObjGet(uint16_t busNum) +{ + char *serviceName = NULL; + void *obj = NULL; + + serviceName = (char *)OsalMemCalloc(EDP_SERVICE_NAME_LEN + 1); + if (serviceName == NULL) { + HDF_LOGE("EDP service name malloc fail."); + return NULL; + } + if (snprintf_s(serviceName, (EDP_SERVICE_NAME_LEN + 1), + EDP_SERVICE_NAME_LEN, "HDF_PLATFORM_EDP_%u", busNum) < 0) { + HDF_LOGE("get EDP service name fail."); + OsalMemFree(serviceName); + return obj; + } + obj = (void *)EdpCntlrGetByBusNum(busNum); + OsalMemFree(serviceName); + return obj; +} + +static int32_t EdpCntlrParseVideoCaps( + struct EdpCntlr *cntlr, struct DeviceResourceIface *drsOps, const struct DeviceResourceNode *node) +{ + int32_t ret; + + ret = drsOps->GetUint32(node, "maxTmdsClock", &(cntlr->cap.maxTmdsClock), 0); + if (ret != HDF_SUCCESS) { + HDF_LOGE("EdpCntlrParseVideoCaps: read maxTmdsClock fail!"); + return ret; + } + + ret = drsOps->GetUint32(node, "defTmdsClock", &(cntlr->cap.defTmdsClock), 0); + if (ret != HDF_SUCCESS) { + HDF_LOGE("EdpCntlrParseVideoCaps: read defTmdsClock fail!"); + return ret; + } + + ret = drsOps->GetUint32(node, "maxFrlRate", &(cntlr->cap.maxFrlRate), 0); + if (ret != HDF_SUCCESS) { + HDF_LOGE("EdpCntlrParseVideoCaps: read maxFrlRate fail!"); + return ret; + } + + ret = drsOps->GetUint32(node, "videoTiming", &(cntlr->cap.videoTiming), 0); + if (ret != HDF_SUCCESS) { + HDF_LOGE("EdpCntlrParseVideoCaps: read videoTiming fail!"); + return ret; + } + + ret = drsOps->GetUint32(node, "quantization", &(cntlr->cap.quantization), 0); + if (ret != HDF_SUCCESS) { + HDF_LOGE("EdpCntlrParseVideoCaps: read quantization fail!"); + return ret; + } + + ret = drsOps->GetUint32(node, "colorSpace", &(cntlr->cap.colorSpace), 0); + if (ret != HDF_SUCCESS) { + HDF_LOGE("EdpCntlrParseVideoCaps: read colorSpace fail!"); + return ret; + } + + ret = drsOps->GetUint32(node, "colorimetry", &(cntlr->cap.colorimetry), 0); + if (ret != HDF_SUCCESS) { + HDF_LOGE("EdpCntlrParseVideoCaps: read colorimetry fail!"); + return ret; + } + return HDF_SUCCESS; +} + +static int32_t EdpCntlrParseAudioCaps( + struct EdpCntlr *cntlr, struct DeviceResourceIface *drsOps, const struct DeviceResourceNode *node) +{ + int32_t ret; + + ret = drsOps->GetUint32(node, "audioIfType", &(cntlr->cap.audioIfType), 0); + if (ret != HDF_SUCCESS) { + HDF_LOGE("EdpCntlrParseAudioCaps: read audioIfType fail!"); + return ret; + } + HDF_LOGD("EdpCntlrParseAudioCaps: audioIfType = %d", cntlr->cap.audioIfType); + + ret = drsOps->GetUint32(node, "audioBitDepth", &(cntlr->cap.audioBitDepth), 0); + if (ret != HDF_SUCCESS) { + HDF_LOGE("EdpCntlrParseAudioCaps: read audioBitDepth fail!"); + return ret; + } + HDF_LOGD("EdpCntlrParseAudioCaps: audioBitDepth = %d", cntlr->cap.audioBitDepth); + + ret = drsOps->GetUint32(node, "audioSampleRate", &(cntlr->cap.audioSampleRate), 0); + if (ret != HDF_SUCCESS) { + HDF_LOGE("EdpCntlrParseAudioCaps: read audioSampleRate fail!"); + return ret; + } + HDF_LOGD("EdpCntlrParseAudioCaps: audioSampleRate = %d", cntlr->cap.audioSampleRate); + + ret = drsOps->GetUint32(node, "audioChannels", &(cntlr->cap.audioChannels), 0); + if (ret != HDF_SUCCESS) { + HDF_LOGE("EdpCntlrParseAudioCaps: read audioChannels fail!"); + return ret; + } + HDF_LOGD("EdpCntlrParseAudioCaps: audioChannels = %d", cntlr->cap.audioChannels); + return HDF_SUCCESS; +} + +int32_t EdpCntlrParse(struct EdpCntlr *cntlr, struct HdfDeviceObject *obj) +{ + const struct DeviceResourceNode *node = NULL; + struct DeviceResourceIface *drsOps = NULL; + int32_t ret = -1; + + if (obj == NULL || cntlr == NULL) { + HDF_LOGE("EdpCntlrParse: input param is NULL."); + return HDF_FAILURE; + } + + node = obj->property; + if (node == NULL) { + HDF_LOGE("EdpCntlrParse: drs node is NULL."); + return HDF_FAILURE; + } + drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); + if (drsOps == NULL || drsOps->GetUint32 == NULL) { + HDF_LOGE("EdpCntlrParse: invalid drs ops fail!"); + return HDF_FAILURE; + } + + ret = drsOps->GetUint32(node, "index", &(cntlr->deviceIndex), 0); + if (ret != HDF_SUCCESS) { + HDF_LOGE("EdpCntlrParse: read hostId fail!"); + return ret; + } + + ret = drsOps->GetUint32(node, "cap", &(cntlr->cap.baseCap.data), 0); + if (ret != HDF_SUCCESS) { + HDF_LOGE("EdpCntlrParse: read baseCap fail!"); + return ret; + } + + ret = EdpCntlrParseVideoCaps(cntlr, drsOps, node); + if (ret != HDF_SUCCESS) { + HDF_LOGE("EdpCntlrParse: read video caps fail!"); + return ret; + } + + ret = EdpCntlrParseAudioCaps(cntlr, drsOps, node); + if (ret != HDF_SUCCESS) { + HDF_LOGE("EdpCntlrParse: read audio caps fail!"); + return ret; + } + return HDF_SUCCESS; +} + +int32_t EdpCntlrAdd(struct HdfDeviceObject *obj, struct EdpCntlr *cntlr) +{ + int32_t ret = -1; + if (obj == NULL || cntlr == NULL) { + HDF_LOGE("%s: invalid parameter", __func__); + return HDF_ERR_INVALID_PARAM; + } + if (cntlr->ops == NULL) { + HDF_LOGE("%s: edp ops is null", __func__); + return HDF_ERR_INVALID_PARAM; + } + if (OsalSpinInit(&(cntlr->lock)) != HDF_SUCCESS) { + HDF_LOGE("%s: init spinlock fail", __func__); + return HDF_FAILURE; + } + cntlr->device.manager = PlatformManagerGet(PLATFORM_MODULE_EDP); + ret = PlatformDeviceAdd(&cntlr->device); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: device add fail!", __func__); + return ret; + } + cntlr->hdfDevObj = obj; + cntlr->hdfDevObj->service = &(cntlr->service); + cntlr->device.hdfDev = obj; + cntlr->device.service = &cntlr->service; + return HDF_SUCCESS; +} + +DevHandle EdpCntlrOpen(uint16_t busNum) +{ + DevHandle hdl = EdpCntlrObjGet(busNum); + return hdl; +} + +int32_t EdpCntlrDeepColorSet(struct EdpCntlr *cntlr, enum EdpColorDepth color) +{ + int32_t ret = -1; + if (cntlr == NULL || cntlr->ops == NULL || cntlr->ops->deepColorSet == NULL) { + return HDF_ERR_INVALID_OBJECT; + } + + ret = cntlr->ops->deepColorSet(cntlr, color); + return ret; +} + +int32_t EdpCntlrDeepColorGet(struct EdpCntlr *cntlr, enum EdpColorDepth *color) +{ + int32_t ret = -1; + if (cntlr == NULL || cntlr->ops == NULL || cntlr->ops->deepColorGet == NULL) { + return HDF_ERR_INVALID_OBJECT; + } + + ret = cntlr->ops->deepColorGet(cntlr, color); + return ret; +} + +int32_t EdpCntlrSetVideoAttribute(struct EdpCntlr *cntlr, const struct EdpVideoAttr * attr) +{ + int32_t ret = HDF_FAILURE; + if (cntlr == NULL || cntlr->ops == NULL || cntlr->ops->setVideoAttribute == NULL) { + return HDF_ERR_INVALID_OBJECT; + } + ret = cntlr->ops->setVideoAttribute(cntlr, attr); + + return ret; +} + +int32_t EdpCntlrGetVideoAttribute(struct EdpCntlr *cntlr, struct EdpVideoAttr * attr) +{ + int32_t ret = HDF_FAILURE; + if (cntlr == NULL || cntlr->ops == NULL || cntlr->ops->getVideoAttribute == NULL) { + return HDF_ERR_INVALID_OBJECT; + } + ret = cntlr->ops->getVideoAttribute(cntlr, attr); + + return ret; +} + +int32_t EdpCntlrSetAudioAttribute(struct EdpCntlr * cntlr, const struct EdpAudioAttr *attr) +{ + int32_t ret = -1; + if (cntlr == NULL || cntlr->ops == NULL || cntlr->ops->setAudioAttribute == NULL) { + return HDF_ERR_INVALID_OBJECT; + } + ret = cntlr->ops->setAudioAttribute(cntlr, attr); + + return ret; +} + +void EdpCntlrClose(struct EdpCntlr *cntlr) +{ + if (cntlr == NULL || cntlr->ops == NULL || cntlr->ops->close == NULL) { + HDF_LOGE("%s: invalid parameter", __func__); + return; + } + cntlr->ops->close(cntlr); +} + +int32_t EdpCntlrRegisterHpdCallbackFunc(struct EdpCntlr *cntlr, struct EdpHpdCallbackInfo *callback) +{ + int32_t ret = -1; + if (cntlr == NULL || callback == NULL || cntlr->ops == NULL || cntlr->ops->registerHpdCallbackFunc == NULL) { + HDF_LOGE("%s: invalid parameter", __func__); + return ret; + } + return cntlr->ops->registerHpdCallbackFunc(cntlr, callback); +} + +int32_t EdpCntlrUnregisterHpdCallbackFunc(struct EdpCntlr *cntlr) +{ + int32_t ret = -1; + if (cntlr == NULL || cntlr->ops == NULL || cntlr->ops->unregisterHpdCallbackFunc == NULL) { + HDF_LOGE("%s: invalid parameter", __func__); + return ret; + } + return cntlr->ops->unregisterHpdCallbackFunc(cntlr); +} + +int32_t EdpCntlrAvmuteSet(struct EdpCntlr *cntlr, bool enable) +{ + int32_t ret = -1; + if (cntlr == NULL || cntlr->ops == NULL || cntlr->ops->avmuteSet == NULL) { + HDF_LOGE("%s: invalid parameter", __func__); + return ret; + } + + EdpCntlrLock(cntlr); + ret = cntlr->ops->avmuteSet(cntlr, enable); + EdpCntlrUnlock(cntlr); + return ret; +} \ No newline at end of file diff --git a/framework/support/platform/src/edp/edp_dispatch.c b/framework/support/platform/src/edp/edp_dispatch.c new file mode 100644 index 000000000..9907f5f24 --- /dev/null +++ b/framework/support/platform/src/edp/edp_dispatch.c @@ -0,0 +1,159 @@ +#include "edp_dispatch.h" +#include "hdf_log.h" +#include "edp_core.h" +#include "edp_if.h" + +#define HDF_LOG_TAG edp_dispatch + +struct EdpDispatchFunc { + uint32_t cmd; + int32_t (*func)(struct EdpCntlr * cntlr, struct HdfSBuf *data, struct HdfSBuf *reply); +}; + +static int32_t EdpCmdOpen(struct EdpCntlr * cntlr, struct HdfSBuf *data, struct HdfSBuf *reply) +{ + (void)data; + (void)reply; + return EdpCntlrOpen(cntlr); +} + +static int32_t EdpCmdClose(struct EdpCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply) +{ + (void)data; + (void)reply; + + EdpCntlrClose(cntlr); + return HDF_SUCCESS; +} +#if 0 +static int32_t EdpCmdStart(struct EdpCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply) +{ + (void)data; + (void)reply; + + return EdpCntlrStart(cntlr); +} + +static int32_t EdpCmdStop(struct EdpCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply) +{ + (void)data; + (void)reply; + + return EdpCntlrStop(cntlr); +} +#endif +static int32_t EdpCmdAvmuteSet(struct EdpCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply) +{ + bool *enable = NULL; + uint32_t size; + (void)reply; + + if (!HdfSbufReadBuffer(data, (const void **)&enable, &size)) { + HDF_LOGE("EdpCmdAvmuteSet: sbuf read buffer failed"); + return HDF_ERR_IO; + } + EdpCntlrAvmuteSet(cntlr, *enable); + return HDF_SUCCESS; +} + +static int32_t EdpCmdDeepColorSet(struct EdpCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply) +{ + enum EdpColorDepth *color = NULL; + uint32_t size; + (void)reply; + + if (!HdfSbufReadBuffer(data, (const void **)&color, &size)) { + HDF_LOGE("EdpCmdDeepColorSet: sbuf read buffer failed"); + return HDF_ERR_IO; + } + return EdpCntlrDeepColorSet(cntlr, *color); +} + +static int32_t EdpCmdDeepColorGet(struct EdpCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply) +{ + int32_t ret; + enum EdpColorDepth color; + (void)data; + + if (reply == NULL) { + return HDF_ERR_INVALID_PARAM; + } + + ret = EdpCntlrDeepColorGet(cntlr, &color); + if (ret != HDF_SUCCESS) { + return ret; + } + + if (HdfSbufWriteBuffer(reply, &color, sizeof(color)) == false) { + HDF_LOGE("EdpCmdDeepColorGet: write back color fail!"); + return HDF_ERR_IO; + } + return HDF_SUCCESS; +} + +static int32_t EdpCmdVideoInfoSet(struct EdpCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply) +{ + struct EdpVideoAttr *attr = NULL; + uint32_t size; + (void)reply; + + if (!HdfSbufReadBuffer(data, (const void **)&attr, &size)) { + HDF_LOGE("EdpCmdVideoInfoSet: sbuf read buffer failed"); + return HDF_ERR_IO; + } + return EdpCntlrSetVideoAttribute(cntlr, attr); +} + +static int32_t EdpCmdAudioInfoSet(struct EdpCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply) +{ + struct EdpAudioAttr *attr = NULL; + uint32_t size; + (void)reply; + + if (!HdfSbufReadBuffer(data, (const void **)&attr, &size)) { + HDF_LOGE("EdpCmdAudioInfoSet: sbuf read buffer failed"); + return HDF_ERR_IO; + } + return EdpCntlrSetAudioAttribute(cntlr, attr); +} + +int32_t EdpIoDispatch(struct HdfDeviceIoClient *client, int cmd, struct HdfSBuf *data, struct HdfSBuf *reply) +{ + struct EdpCntlr *cntlr = NULL; + uint32_t i; + uint32_t len; + struct EdpDispatchFunc dispatchFunc[] = { + { EDP_CMD_OPEN, EdpCmdOpen }, + { EDP_CMD_CLOSE, EdpCmdClose }, + #if 0 + { EDP_CMD_START, EdpCmdStart }, + { EDP_CMD_STOP, EdpCmdStop }, + #endif + { EDP_CMD_AVMUTE_SET, EdpCmdAvmuteSet }, + { EDP_CMD_DEEP_COLOR_SET, EdpCmdDeepColorSet }, + { EDP_CMD_DEEP_COLOR_GET, EdpCmdDeepColorGet }, + { EDP_CMD_VIDEO_ATTR_SET, EdpCmdVideoInfoSet }, + { EDP_CMD_AUDIO_ATTR_SET, EdpCmdAudioInfoSet }, + }; + + if (client == NULL || client->device == NULL) { + HDF_LOGE("EdpIoDispatch: client or hdf dev obj is NULL"); + return HDF_ERR_INVALID_OBJECT; + } + + cntlr = (struct EdpCntlr *)client->device->service; + if (cntlr == NULL) { + HDF_LOGE("EdpIoDispatch: service is NULL"); + return HDF_ERR_INVALID_OBJECT; + } + + len = sizeof(dispatchFunc) / sizeof(dispatchFunc[0]); + for (i = 0; i < len; i++) { + if (dispatchFunc[i].cmd == cmd) { + return dispatchFunc[i].func(cntlr, data, reply); + } + } + + HDF_LOGE("EdpIoDispatch: cmd %d is not support", cmd); + return HDF_ERR_NOT_SUPPORT; +} diff --git a/framework/support/platform/src/edp/edp_if.c b/framework/support/platform/src/edp/edp_if.c new file mode 100644 index 000000000..664e57643 --- /dev/null +++ b/framework/support/platform/src/edp/edp_if.c @@ -0,0 +1,99 @@ +#include "edp_if.h" +#include "hdf_base.h" +#include "hdf_log.h" +#include "osal_mem.h" +#include "edp_core.h" +#include "securec.h" + +#define HDF_LOG_TAG "edp_if" + +static void * EdpGetDevByNum(uint16_t busNum) +{ + char *pSrvcName = NULL; + void *pHdl = NULL; + + pSrvcName = (char *)OsalMemCalloc(EDP_NAME_BUF_LEN); + if (pSrvcName == NULL) { + HDF_LOGE("Edp service name malloc fail."); + return NULL; + } + if (snprintf_s(pSrvcName, (EDP_NAME_BUF_LEN), + EDP_NAME_BUF_LEN -1, "HDF_PLATFORM_EDP_%u", busNum) < 0) { + HDF_LOGE("Generate Edp service name fail."); + OsalMemFree(pSrvcName); + return NULL; + } + +#ifdef __USER__ + pHdl = (void *)HdfIoServiceBind(serviceName); +#else + pHdl = EdpCntlrGetByBusNum(busNum); +#endif + OsalMemFree(pSrvcName); + + return pHdl; +} + +DevHandle EdpOpen(uint16_t busNum) +{ + DevHandle devHdl = (DevHandle)EdpGetDevByNum(busNum); + if (NULL == devHdl){ + HDF_LOGE(" Edp handle get fail."); + return NULL; + } + + return devHdl; +} + +int32_t EdpStart(DevHandle handle) +{ + return HDF_SUCCESS; +} + +int32_t EdpStop(DevHandle handle) +{ + return HDF_SUCCESS; +} + +int32_t EdpAvmuteSet(DevHandle handle, bool enable) +{ + return EdpCntlrAvmuteSet((struct EdpCntlr *)handle, enable); +} + +int32_t EdpDeepColorSet(DevHandle handle, enum EdpColorDepth color) +{ + return EdpCntlrDeepColorSet((struct EdpCntlr *)handle, color); +} + +int32_t EdpDeepColorGet(DevHandle handle, enum EdpColorDepth *color) +{ + return EdpCntlrDeepColorGet((struct EdpCntlr *)handle, color); +} + +int32_t EdpSetVideoAttribute(DevHandle handle, struct EdpVideoAttr *attr) +{ + return EdpCntlrSetVideoAttribute((struct EdpCntlr *)handle, attr); +} + +int32_t EdpSetAudioAttribute(DevHandle handle, struct EdpAudioAttr *attr) +{ + return EdpCntlrSetAudioAttribute((struct EdpCntlr *)handle, attr); +} + +int32_t EdpRegisterHpdCallbackFunc( + DevHandle handle, + struct EdpHpdCallbackInfo *callback) +{ + // not support yet + return EdpCntlrRegisterHpdCallbackFunc((struct EdpCntlr *)handle, callback); +} + +int32_t EdpUnregisterHpdCallbackFunc(DevHandle handle) +{ + return EdpCntlrUnregisterHpdCallbackFunc((struct EdpCntlr *)handle); +} + +void EdpClose(DevHandle handle) +{ + EdpCntlrClose((struct EdpCntlr *)handle); +} \ No newline at end of file -- Gitee