// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
/*
 * Copyright (c) 2020 MediaTek Inc.
 */
/*
 * Copyright 2024 Sony Corporation
 */

#include <linux/module.h>
#include <linux/fs.h>
#include <linux/timer.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/clk.h>
#include <linux/interrupt.h>
#include <linux/of.h>
#include <linux/types.h>
#include <linux/platform_device.h>
#include <uapi/linux/mtk-v4l2-pq.h>
#include <linux/videodev2.h>
#include <linux/uaccess.h>
#include <linux/version.h>

#include <media/v4l2-mem2mem.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-vmalloc.h>
#include <media/v4l2-ctrls.h>

#include "mtk_pq.h"
#include "mtk_pq_pqd.h"
#include "mtk_pq_dv.h"
#include "pqu_msg.h"
#include "m_pqu_pq.h"
#include "mtk_pq_common.h"
#include "ext_command_video_if.h"
/* Sony modification start */
#include "mtk_pq_pqd_sony.h"
/* Sony modification end */

#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0)
MODULE_IMPORT_NS(DMA_BUF);
#endif

//-----------------------------------------------------------------------------
//  Local Defines
//-----------------------------------------------------------------------------
#define UNUSED_PARA(x) (void)(x)
//-----------------------------------------------------------------------------
//  Local Variables
//-----------------------------------------------------------------------------
#define _READY_CB_COUNT 8
#define _CB_INC(x) ((x++)&(_READY_CB_COUNT-1))
#define _CB_DEC(x) (x == 0 ? 0 : --x)

static struct msg_pqmap_info _pqmap_msg_info;
static struct msg_pqmeta_info _pqmeta_msg_info;
static struct msg_pqparam_info _pqparam_msg_info[_READY_CB_COUNT];
static int _pqparam_count;

//-----------------------------------------------------------------------------
// LOCAL FUNCTION
//-----------------------------------------------------------------------------
static int _mtk_pqd_map_fd(int fd, void **va, u64 *size, struct dma_buf **db)
{
	int ret = 0;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 17, 0)
	struct iosys_map map = IOSYS_MAP_INIT_VADDR(NULL);
#else
	struct dma_buf_map map = DMA_BUF_MAP_INIT_VADDR(NULL);
#endif

	if ((size == NULL) || (fd == 0) || (va == NULL)) {
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR,
			"Invalid input, fd=(%d), size is NULL?(%s), va is NULL?(%s)\n",
			fd, (size == NULL)?"TRUE":"FALSE", (va == NULL)?"TRUE":"FALSE");
		return -EPERM;
	}

	(*db) = dma_buf_get(fd);
	if (IS_ERR_OR_NULL((*db))) {
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR, "dma_buf_get fail\n");
		return -EPERM;
	}

	*size = (*db)->size;

	ret = dma_buf_vmap((*db), &map);
	if (ret)
		map.vaddr = NULL;
	*va = map.vaddr;

	if (IS_ERR_OR_NULL(*va)) {
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR, "dma_buf_vmapfail\n");
		dma_buf_put((*db));
		return -EPERM;
	}
	STI_PQ_LOG(STI_PQ_LOG_LEVEL_ENHANCE, "va=0x%llx, size=%llu\n", (__u64)*va, (__u64)*size);
	return ret;
}

static int _mtk_pqd_unmap_fd(int fd, void **va, struct dma_buf **db)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 17, 0)
	struct iosys_map map = IOSYS_MAP_INIT_VADDR((*va));
#else
	struct dma_buf_map map = DMA_BUF_MAP_INIT_VADDR((*va));
#endif
	if ((va == NULL) || (fd == 0) || (db == NULL)) {
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR,
			"Invalid input, fd=(%d), va is NULL?(%s) db is NULL?(%s)\n",
			fd, (va == NULL)?"TRUE":"FALSE",
			(va == NULL)?"TRUE":"FALSE");
		return -EPERM;
	}
	STI_PQ_LOG(STI_PQ_LOG_LEVEL_ENHANCE, "va=0x%llx\n", (__u64)*va);
	if (((*va) == NULL) || ((*db) == NULL)) {
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR,
			"(((*va) == NULL)||((*db) == NULL)) no need unmap!\n");
		return -0;
	}
	dma_buf_vunmap((*db), &map);
	dma_buf_put(*db);
	(*db) = NULL;
	(*va) = NULL;
	return 0;
}

//-----------------------------------------------------------------------------
//  FUNCTION
//-----------------------------------------------------------------------------
int mtk_pqd_LoadPQSetting(struct st_pqd_info *pqd_info,
	__s32 load_enable)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(load_enable);

	return 0;
}

int mtk_pqd_SetPointToPoint(
	struct st_pqd_info *pqd_info, __s32 is_enable)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(is_enable);

	return 0;
}

int mtk_pqd_LoadPTPTable(struct st_pqd_info *pqd_info,
	__s32 ptp_type)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ptp_type);

	return 0;
}

int mtk_pqd_ACE_3DClonePQMap(
	struct st_pqd_info *pqd_info, __s32 weave_type)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(weave_type);

	return 0;
}

int mtk_pqd_Set3DCloneforPIP(struct st_pqd_info *pqd_info,
	__s32 pip_enable)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(pip_enable);

	return 0;
}

int mtk_pqd_Set3DCloneforLBL(struct st_pqd_info *pqd_info,
	__s32 lbl_enable)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(lbl_enable);

	return 0;
}

int mtk_pqd_SetGameMode(struct st_pqd_info *pqd_info,
	__s32 game_enable)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(game_enable);

	return 0;
}

int mtk_pqd_SetBOBMode(struct st_pqd_info *pqd_info,
	__s32 bob_enable)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(bob_enable);

	return 0;
}

int mtk_pqd_SetBypassMode(struct st_pqd_info *pqd_info,
	__s32 bypass_enable)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(bypass_enable);

	return 0;
}

int mtk_pqd_DemoCloneWindow(struct st_pqd_info *pqd_info,
	__s32 mode)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(mode);

	return 0;
}

int mtk_pqd_ReduceBWforOSD(struct st_pqd_info *pqd_info,
	__s32 osd_on)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(osd_on);

	return 0;
}

int mtk_pqd_EnableHDRMode(struct st_pqd_info *pqd_info,
	__s32 grule_level_index)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(grule_level_index);

	return 0;
}

int mtk_pqd_PQExit(struct st_pqd_info *pqd_info,
	__s32 exit_enable)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(exit_enable);

	return 0;
}

int mtk_pqd_ACE_SetRBChannelRange(
	struct st_pqd_info *pqd_info, __s32 range_enable)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(range_enable);

	return 0;
}

int mtk_pqd_SetFilmMode(struct st_pqd_info *pqd_info,
	__s32 film_mode)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(film_mode);

	return 0;
}

int mtk_pqd_SetNRMode(struct st_pqd_info *pqd_info,
	__s32 nr_mode)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(nr_mode);

	return 0;
}

int mtk_pqd_SetMPEGNRMode(
	struct st_pqd_info *pqd_info, __s32 mpeg_nr_mode)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(mpeg_nr_mode);

	return 0;
}

int mtk_pqd_SetXvyccMode(struct st_pqd_info *pqd_info,
	__s32 xvycc_mode)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(xvycc_mode);

	return 0;
}

int mtk_pqd_SetDLCMode(struct st_pqd_info *pqd_info,
	__s32 dlc_mode)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(dlc_mode);

	return 0;
}

int mtk_pqd_SetSWDRMode(struct st_pqd_info *pqd_info,
	__s32 swdr_mode)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(swdr_mode);

	return 0;
}

int mtk_pqd_SetDynamicContrastMode(
	struct st_pqd_info *pqd_info, __s32 contrast_type)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(contrast_type);

	return 0;
}

int mtk_pqd_ACE_SetContrast(struct st_pqd_info *pqd_info,
	__s32 contrast_value)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(contrast_value);

	return 0;
}

int mtk_pqd_ACE_SetBrightness(struct st_pqd_info *pqd_info,
	__s32 brightness_value)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(brightness_value);

	return 0;
}

int mtk_pqd_ACE_SetHue(struct st_pqd_info *pqd_info,
	__s32 hue_value)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(hue_value);

	return 0;
}

int mtk_pqd_ACE_SetSaturation(struct st_pqd_info *pqd_info,
	__s32 saturation_value)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(saturation_value);

	return 0;
}

int mtk_pqd_ACE_SetSharpness(struct st_pqd_info *pqd_info,
	__s32 sharpness_value)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(sharpness_value);

	return 0;
}


/////////////////////////////////////////set extern ctrl///////////////////////
int mtk_pqd_SetDbgLevel(struct st_pqd_info *pqd_info,
	void *ctrl)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ctrl);

	return 0;
}

int mtk_pqd_SetPQInit(struct st_pqd_info *pqd_info, void *ctrl)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ctrl);

	return 0;
}

int mtk_pqd_MADIForceMotion(struct st_pqd_info *pqd_info,
	void *ctrl)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ctrl);

	return 0;
}

int mtk_pqd_SetRFBLMode(struct st_pqd_info *pqd_info,
	void *ctrl)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ctrl);

	return 0;
}

int mtk_pqd_SetGruleStatus(struct st_pqd_info *pqd_info,
	void *ctrl)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ctrl);

	return 0;
}

int mtk_pqd_SetUCDMode(struct st_pqd_info *pqd_info,
	void *ctrl)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ctrl);

	return 0;
}

int mtk_pqd_SetHSBBypass(struct st_pqd_info *pqd_info,
	void *ctrl)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ctrl);

	return 0;
}

int mtk_pqd_SetVersion(struct st_pqd_info *pqd_info,
	void *ctrl)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ctrl);

	return 0;
}

int mtk_pqd_SetHSYGrule(struct st_pqd_info *pqd_info,
	void *ctrl)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ctrl);

	return 0;
}

int mtk_pqd_SetFBLStatus(struct st_pqd_info *pqd_info,
	void *ctrl)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ctrl);

	return 0;
}

int mtk_pqd_SetIPHistogram(__u16 dev_indx, struct st_pqd_info *pqd_info, void *ctrl,
	void *pq_pa_addr, void *pq_va_addr, __u32 pq_bus_buf_size)
{
	struct msg_histogram_info msg_info;
	struct m_pq_histogram_info *pHistogram_info = NULL;
	struct v4l2_pq_histogram_info table;
	int ret = 0;

	UNUSED_PARA(pqd_info);

	memset(&msg_info, 0, sizeof(struct msg_histogram_info));
	memcpy(&table, ctrl, sizeof(struct v4l2_pq_histogram_info));

	if (bPquEnable) {
		if ((!pq_pa_addr) || (!pq_va_addr)) {
			STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR, "NULL parameters!\n");
			return -EFAULT;
		}

		pHistogram_info = (void *)pq_va_addr;

		msg_info.win_id = (__u8)dev_indx;
		msg_info.va = (__u64)pq_va_addr;
		msg_info.pa = (__u64)pq_pa_addr;
		msg_info.size = (__u64)pq_bus_buf_size;

		ret = pqu_video_set_iphistogram((void *)&msg_info);
		if (ret != 0) {
			STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR,
				"pqu_video_set_iphistogram fail (ret=%d)\n", ret);
		}
		memcpy(ctrl, pHistogram_info, sizeof(struct m_pq_histogram_info));

	} else {
		pqu_histogram_set_param(dev_indx, (struct m_pq_histogram_info *)(ctrl));
	}

	return ret;
}

int mtk_pqd_SetNRSettings(struct st_pqd_info *pqd_info,
	void *ctrl)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ctrl);

	return 0;
}

int mtk_pqd_SetDPUMode(struct st_pqd_info *pqd_info, void *ctrl)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ctrl);

	return 0;
}

int mtk_pqd_ACE_SetCCMInfo(struct st_pqd_info *pqd_info,
	void *ctrl)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ctrl);

	return 0;
}

int mtk_pqd_ACE_SetColorTuner(struct st_pqd_info *pqd_info,
	void *ctrl)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ctrl);

	return 0;
}

int mtk_pqd_ACE_SetHSYSetting(struct st_pqd_info *pqd_info,
	void *ctrl)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ctrl);

	return 0;
}

int mtk_pqd_ACE_SetHSYRange(struct st_pqd_info *pqd_info,
	void *ctrl)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ctrl);

	return 0;
}

int mtk_pqd_ACE_SetManualLumaCurve(
	struct st_pqd_info *pqd_info, void *ctrl)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ctrl);

	return 0;
}

int mtk_pqd_ACE_SetStretchSettings(
	struct st_pqd_info *pqd_info, void *ctrl)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ctrl);

	return 0;
}

int mtk_pqd_ACE_SetPQCmd(struct st_pqd_info *pqd_info,
	void *ctrl)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ctrl);

	return 0;
}

int mtk_pqd_ACE_SetPostColorTemp(
	struct st_pqd_info *pqd_info, void *ctrl)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ctrl);

	return 0;
}

int mtk_pqd_ACE_SetMWE(struct st_pqd_info *pqd_info,
	void *ctrl)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ctrl);

	return 0;
}

int mtk_pqd_SetSWDRInfo(struct st_pqd_info *pqd_info,
	void *ctrl)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ctrl);

	return 0;
}

int mtk_pqd_GenRGBPattern(struct st_pqd_info *pqd_info,
	void *ctrl)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ctrl);

	return 0;
}

int mtk_pqd_SetBlueStretch(struct st_pqd_info *pqd_info,
	void *ctrl)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ctrl);

	return 0;
}

int mtk_pqd_Set_H_NonlinearScaling(
	struct st_pqd_info *pqd_info, void *ctrl)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ctrl);

	return 0;
}

int mtk_pqd_SetMCDIMode(struct st_pqd_info *pqd_info,
	void *ctrl)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ctrl);

	return 0;
}

int mtk_pqd_SetChromaInfo(struct st_pqd_info *pqd_info,
	void *ctrl)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ctrl);

	return 0;
}

int mtk_pqd_SetPQGamma(struct st_pqd_info *pqd_info,
	void *ctrl)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ctrl);

	return 0;
}

int mtk_pqd_SetVideoDelayTime(struct st_pqd_info *pqd_info,
	void *ctrl)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ctrl);

	return 0;
}

int mtk_pqd_DLCInit(struct st_pqd_info *pqd_info,
	void *ctrl)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ctrl);

	return 0;
}

int mtk_pqd_SetDLCCaptureRange(
	struct st_pqd_info *pqd_info, void *ctrl)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ctrl);

	return 0;
}

static void _mtk_pqd_ready_setPQMapInfo(void)
{
	int ret = 0;

	STI_PQ_LOG(STI_PQ_LOG_LEVEL_DBG, "pqu cpuif ready callback function\n");

	ret = pqu_video_pqmap_setup((void *)&_pqmap_msg_info);
	if (ret != 0)
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR, "pqu_video_pqmap_setup fail! (ret=%d)\n", ret);
}

int mtk_pqd_resumeSetPQMapInfo(struct mtk_pq_platform_device *pqdev)
{
	int ret = 0;

	if (!pqdev) {
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR, "NULL parameters!\n");
		return -EFAULT;
	}

	if (_pqmap_msg_info.start_addr == 0) {
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR, "resume send pqmap va to pqu fail!\n");
		ret = -EINVAL;
		return ret;
	}

	dma_sync_single_for_device(pqdev->dev,
		_pqmap_msg_info.start_addr,
		_pqmap_msg_info.max_size,
		DMA_TO_DEVICE);

	ret = pqu_video_pqmap_setup((void *)&_pqmap_msg_info);
	if (ret == -ENODEV) {
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR, "pqu_video_pqmap_setup register ready cb!\n");
		ret = fw_ext_command_register_notify_ready_callback(0, _mtk_pqd_ready_setPQMapInfo);
		return ret;
	} else if (ret != 0) {
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR,
			"pqu_video_pqmap_setup fail (ret=%d)\n", ret);
	}

	return ret;
}

int mtk_pqd_SetPQMapInfo(struct mtk_pq_platform_device *pqdev,
	struct st_pqd_info *pqd_info, void *ctrl, void *pq_pa_addr,
	void *pq_va_addr, __u32 pq_bus_buf_size)
{
	struct v4l2_pqmap_info table;
	struct msg_pqmap_info msg_info;
	int ret = 0;

	if ((!pqd_info) || (!ctrl) || (!pqdev)) {
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR, "NULL parameters!\n");
		return -EFAULT;
	}

	memset(&table, 0, sizeof(struct v4l2_pqmap_info));
	memset(&msg_info, 0, sizeof(struct msg_pqmap_info));
	memcpy(&table, ctrl, sizeof(struct v4l2_pqmap_info));

	if ((table.u32MainPimLen == 0) && (table.u32MainRmLen == 0) &&
		(table.u32MainExPimLen == 0) && (table.u32MainExRmLen == 0)) {
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR, "no pqmap here, no need to get va\n");
		return 0;
	}

	msg_info.start_addr = (__u64)pq_va_addr;
	msg_info.max_size = pq_bus_buf_size;
	msg_info.u32MainPimLen = table.u32MainPimLen;
	msg_info.u32MainRmLen = table.u32MainRmLen;
	msg_info.u32MainExPimLen = table.u32MainExPimLen;
	msg_info.u32MainExRmLen = table.u32MainExRmLen;
	u32PQMapBufLen = table.u32MainPimLen + table.u32MainRmLen
		+ table.u32MainExPimLen + table.u32MainExRmLen;

	if (bPquEnable) {
		dma_sync_single_for_device(pqdev->dev,
			(__u64)pq_pa_addr,
			pq_bus_buf_size,
			DMA_TO_DEVICE);
		msg_info.start_addr = (__u64)pq_pa_addr;
		memcpy(&_pqmap_msg_info, &msg_info, sizeof(struct msg_pqmap_info));
		ret = pqu_video_pqmap_setup((void *)&msg_info);
		if (ret == -ENODEV) {
			STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR, "send pqmap va to pqu timing fail\n");
			ret = fw_ext_command_register_notify_ready_callback(0,
								_mtk_pqd_ready_setPQMapInfo);
			return ret;
		} else if (ret != 0) {
			STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR,
				"pqu_video_pqmap_setup fail (ret=%d)\n", ret);
		}
	} else {
		if (pqdev->pqcaps.u32Qmap_Heap_Support != 0) {
			void *va = NULL;
			u64 size = 0;
			struct dma_buf *db = NULL;

			if (_mtk_pqd_map_fd(table.fd, &va, &size, &db) != 0) {
				STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR,
					"_mtk_pqd_map_fd fail\n");
				_mtk_pqd_unmap_fd(table.fd, &va, &db);
				return -EFAULT;
			}
			STI_PQ_LOG(STI_PQ_LOG_LEVEL_ENHANCE, "start_addr:%llx, max_size:%llu\n",
				(__u64)va, size);
			msg_info.start_addr = (__u64)va;
			msg_info.max_size = size;
		} else {
			dma_sync_single_for_device(pqdev->dev,
				(__u64)pq_pa_addr,
				pq_bus_buf_size,
				DMA_TO_DEVICE);
		}
		pqu_msg_send(PQU_MSG_SEND_PQMAP, (void *)&msg_info);
	}

	STI_PQ_LOG(STI_PQ_LOG_LEVEL_ENHANCE, "send pqmap va to pqu done\n");

	return 0;
}

int mtk_pqd_SetDIPMapInfo(struct mtk_pq_platform_device *pqdev,
	struct st_pqd_info *pqd_info, void *ctrl, void *pq_pa_addr,
	void *pq_va_addr, __u32 pq_bus_buf_size)
{
	struct v4l2_dipmap_info table;
	struct msg_dipmap_info msg_info;

	if ((!pqd_info) || (!ctrl))
		return -EFAULT;

	memset(&table, 0, sizeof(struct v4l2_dipmap_info));
	memset(&msg_info, 0, sizeof(struct msg_dipmap_info));
	memcpy(&table, ctrl, sizeof(struct v4l2_dipmap_info));

	if ((table.u32MainPimLen == 0) && (table.u32MainRmLen == 0) &&
		(table.u32MainExPimLen == 0) && (table.u32MainExRmLen == 0)) {
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR, "no pqmap here, no need to get va\n");
		return -EFAULT;
	}

	msg_info.start_addr = (__u64)pq_va_addr;
	msg_info.max_size = pq_bus_buf_size;
	msg_info.u32MainPimLen = table.u32MainPimLen;
	msg_info.u32MainRmLen = table.u32MainRmLen;
	msg_info.u32MainExPimLen = table.u32MainExPimLen;
	msg_info.u32MainExRmLen = table.u32MainExRmLen;

	if (pqdev->pqcaps.u32Qmap_Heap_Support != 0) {
		void *va = NULL;
		u64 size = 0;
		struct dma_buf *db = NULL;

		if (_mtk_pqd_map_fd(table.fd, &va, &size, &db) != 0) {
			STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR,
				"_mtk_pqd_map_fd fail\n");
			_mtk_pqd_unmap_fd(table.fd, &va, &db);
			return -EFAULT;
		}
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ENHANCE, "start_addr:%llx, max_size:%llu\n",
			(__u64)va, size);
		msg_info.start_addr = (__u64)va;
		msg_info.max_size = size;
	}
	pqu_msg_send(PQU_MSG_SEND_DIPMAP, (void *)&msg_info);

	STI_PQ_LOG(STI_PQ_LOG_LEVEL_ENHANCE, "senddipmap va to pqu done\n");

	return 0;
}

static void _ready_cb_pqu_video_pqmeta_update(void)
{
	int ret = 0;

	STI_PQ_LOG(STI_PQ_LOG_LEVEL_DBG, "pqu cpuif ready callback function\n");

	ret = pqu_video_pqmeta_update((void *)&_pqmeta_msg_info);
	if (ret)
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR, "pqu_video_pqmeta_update fail!\n");
}

int mtk_pqd_SetPQMetaData(struct st_pqd_info *pqd_info,
	void *ctrl)
{
	int ret = 0;
	struct v4l2_pq_metadata table;
	struct msg_pqmeta_info msg_info;
	static void *va[PQ_WIN_MAX_NUM] = {NULL};
	static u64 size[PQ_WIN_MAX_NUM] = {0};
	static struct dma_buf *db[PQ_WIN_MAX_NUM] = {NULL};
	uint8_t win_id = 0;
	static __u32 fd[PQ_WIN_MAX_NUM] = { [0 ... (PQ_WIN_MAX_NUM-1)] = -1};
	if ((!pqd_info) || (!ctrl))
		return -EFAULT;
	memset(&table, 0, sizeof(struct v4l2_pq_metadata));
	memset(&msg_info, 0, sizeof(struct msg_pqmeta_info));
	memcpy(&table, ctrl, sizeof(struct v4l2_pq_metadata));
	if (table.fd == -1) {
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR, "invalid fd\n");
		return 0;
	}
	STI_PQ_LOG(STI_PQ_LOG_LEVEL_ENHANCE, "pqmeta fd = %d\n", table.fd);
	win_id = table.win_id;
	if (table.enable == true) {
		if (fd[win_id] != table.fd) {
			if ((db[win_id]) || (va[win_id])) {
				if (_mtk_pqd_unmap_fd(table.fd, &va[win_id], &db[win_id])) {
					STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR,
						"_mtk_pqd_unmap_fd fail\n");
					return -EFAULT;
				}
				STI_PQ_LOG(STI_PQ_LOG_LEVEL_ENHANCE, "release fd[%u]:%d\n",
					win_id, fd[win_id]);
			}
			if (_mtk_pqd_map_fd(table.fd, &va[win_id],
				&size[win_id], &db[win_id]) != 0) {
				STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR, "_mtk_pqd_map_fd fail!\n");
				return -EFAULT;
			}
			STI_PQ_LOG(STI_PQ_LOG_LEVEL_ENHANCE, "map fd[%u]:%d\n",
				win_id, fd[win_id]);
			fd[win_id] = table.fd;
			STI_PQ_LOG(STI_PQ_LOG_LEVEL_ENHANCE, "update fd[%u]:%d\n",
				win_id, fd[win_id]);
		}
		//ION Version, fix it after use pqmap pa
		msg_info.fd = table.fd;
		msg_info.meta_pa = (__u64)va[win_id];
		msg_info.meta_size = size[win_id];
		msg_info.win_id = table.win_id;
		//ION Version, fix it after use pqmap pa
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ENHANCE, "va = %llx\n",
			msg_info.meta_pa);
		if (bPquEnable) {
			memcpy(&_pqmeta_msg_info, &msg_info, sizeof(struct msg_pqmeta_info));
			ret = pqu_video_pqmeta_update((void *)&msg_info);
			if (ret == -ENODEV) {
				STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR,
					"pqu_video_pqmeta_update register ready cb\n");
				ret = fw_ext_command_register_notify_ready_callback(0,
					_ready_cb_pqu_video_pqmeta_update);
			} else if (ret != 0) {
				STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR,
					"pqu_video_pqmeta_update fail (ret=%d)\n", ret);
			}
		}
		else
			pqu_msg_send(PQU_MSG_SEND_PQMETA, (void *)&msg_info);
	} else {
		if (_mtk_pqd_unmap_fd(table.fd, &va[win_id], &db[win_id]) != 0) {
			STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR, "_mtk_pqd_unmap_fd fail!\n");
			return -EFAULT;
		}
		fd[win_id] = -1;
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ENHANCE, "release fd[%u]:%d\n", win_id, fd[win_id]);
	}
	return 0;
}

static void _ready_cb_pqu_video_pqparam_update(void)
{
	int ret = 0;
	struct callback_info pqparam_callback_info = {0};

	STI_PQ_LOG(STI_PQ_LOG_LEVEL_DBG, "pqu cpuif ready callback function\n");

	ret = pqu_video_pqparam_update((void *)&_pqparam_msg_info[_CB_DEC(_pqparam_count)],
		&pqparam_callback_info);
	if (ret)
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR, "pqu_video_pqparam_update fail!\n");
}

int _mtk_pqd_SetGCEParam(struct meta_buffer *pqu_buf, struct meta_buffer *pqhal_buf)
{
	struct meta_pq_gceparam *pstGCEparamPqhal;
	int ret = 0;

	if (!pqu_buf) {
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR, "Invalid pqu_buf input\n");
		return -EFAULT;
	}
	if (!pqhal_buf) {
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR, "Invalid pqhal_buf input\n");
		return -EFAULT;
	}

	/* read metadata written by pqhal */
	ret = mtk_pq_common_read_metadata_addr_ptr(pqhal_buf,
		EN_PQ_METATAG_GCEPARAM_TAG, (void **)&pstGCEparamPqhal);
	if (ret) {
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ENHANCE, "GCE param don't need to update\n");
		return 0;
	}

	/* write metadata for pqu read */
	ret = mtk_pq_common_write_metadata_addr(pqu_buf,
		EN_PQ_METATAG_PQU_GCEPARAM_TAG, (void *)pstGCEparamPqhal);
	if (ret) {
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR,
			" write EN_PQ_METATAG_PQU_GCEPARAM_TAG Failed, ret = %d\n", ret);
		return -EFAULT;
	}

	return 0;
}

int _mtk_pqd_SetLocalHSY(struct meta_buffer *pqu_buf, struct meta_buffer *pqhal_buf)
{
	struct meta_pq_localhsy *pstLocalhsyPqhal = NULL;
	int ret = 0;

	if (!pqu_buf) {
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR, "Invalid pqu_buf input\n");
		return -EFAULT;
	}
	if (!pqhal_buf) {
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR, "Invalid pqhal_buf input\n");
		return -EFAULT;
	}

	/* read metadata written by pqhal */
	ret = mtk_pq_common_read_metadata_addr_ptr(pqhal_buf,
		EN_PQ_METATAG_LOCALHSY_TAG, (void **)&pstLocalhsyPqhal);
	if (ret) {
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ENHANCE, "Local HSY don't need to update\n");
		return 0;
	}

	/* write metadata for pqu read */
	ret = mtk_pq_common_write_metadata_addr(pqu_buf,
		EN_PQ_METATAG_PQU_LOCALHSY_TAG, (void *)pstLocalhsyPqhal);
	if (ret) {
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR,
			" write EN_PQ_METATAG_PQU_LOCALHSY_TAG Failed, ret = %d\n", ret);
		return -EFAULT;
	}

	return 0;
}

int _mtk_pqd_SetPQParam(struct meta_buffer *pqu_buf, struct meta_buffer *pqhal_buf)
{
	struct meta_pq_pqparam *pstPqparamPqhal = NULL;
	int ret = 0;

	if (!pqu_buf) {
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR, "Invalid meta_buf input\n");
		return -EFAULT;
	}
	if (!pqhal_buf) {
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR, "Invalid meta_buf input\n");
		return -EFAULT;
	}

	/* read metadata written by pqhal */
	ret = mtk_pq_common_read_metadata_addr_ptr(pqhal_buf,
		EN_PQ_METATAG_PQPARAM_TAG, (void **)&pstPqparamPqhal);
	if (ret) {
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR, "va:%#llx, size:%x\n",
			(__u64)pqhal_buf->paddr, pqhal_buf->size);
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR,
			" read EN_PQ_METATAG_PQPARAM_TAG Failed, ret = %d\n", ret);
		return -EFAULT;
	}

	/* write metadata for pqu read */
	ret = mtk_pq_common_write_metadata_addr(pqu_buf,
		EN_PQ_METATAG_PQU_PQPARAM_TAG, (void *)pstPqparamPqhal);
	if (ret) {
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR, "va:%#llx, size:%x\n",
			(__u64)pqu_buf->paddr, pqu_buf->size);
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR,
			" write EN_PQ_METATAG_PQU_PQPARAM_TAG Failed, ret = %d\n", ret);
		return -EFAULT;
	}

	return 0;
}

int _mtk_pqd_SetLocalVAC(struct meta_buffer *pqu_buf, struct meta_buffer *pqhal_buf)
{
	struct meta_pq_localvac *pstLocalvacPqhal = NULL;
	static struct m_pq_localvac stLocalvacPqu;
	int ret = 0;
	int i = 0;

	if (!pqu_buf) {
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR, "Invalid pqu_buf input\n");
		return -EFAULT;
	}
	if (!pqhal_buf) {
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR, "Invalid pqhal_buf input\n");
		return -EFAULT;
	}

	memset(&stLocalvacPqu, 0, sizeof(struct m_pq_localvac));

	/* read metadata written by pqhal */
	ret = mtk_pq_common_read_metadata_addr_ptr(pqhal_buf,
		EN_PQ_METATAG_LOCALVAC_TAG, (void **)&pstLocalvacPqhal);
	if (ret) {
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ENHANCE, "Local HSY don't need to update\n");
		return 0;
	}

	switch (pstLocalvacPqhal->type) {
	case M_PQ_VAC_POS_RANGE_1024:
		stLocalvacPqu.type = PQU_VAC_POS_RANGE_1024;
		break;
	case M_PQ_VAC_POS_RANGE_2048:
		stLocalvacPqu.type = PQU_VAC_POS_RANGE_2048;
		break;
	case M_PQ_VAC_POS_RANGE_4096:
		stLocalvacPqu.type = PQU_VAC_POS_RANGE_4096;
		break;
	case M_PQ_VAC_POS_RANGE_8192:
		stLocalvacPqu.type = PQU_VAC_POS_RANGE_8192;
		break;
	default:
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR,
			"pstLocalvacPqhal->type undefine %d\n", pstLocalvacPqhal->type);
		return -EFAULT;
	}

	for (i = 0; i < PQU_VAC_SAT_BY_MAX; i++) {
		stLocalvacPqu.en[i] = pstLocalvacPqhal->en[i];
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ENHANCE,
			"en[%d] %d\n", i, stLocalvacPqu.en[i]);
	}

	for (i = 0; i < PQU_PQ_HSYVAC_SAT_BY_HUE_LEN; i++) {
		stLocalvacPqu.u8SatbyHueLut[i] = pstLocalvacPqhal->u8SatbyHueLut[i];
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ENHANCE,
			"u8SatbyHueLut[%d] %d\n", i, stLocalvacPqu.u8SatbyHueLut[i]);
	}

	for (i = 0; i < PQU_PQ_HSYVAC_SAT_BY_POS_LEN; i++) {
		stLocalvacPqu.u8SatbyPosLut[i] = pstLocalvacPqhal->u8SatbyPosLut[i];
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ENHANCE,
			"u8SatbyPosLut[%d] %d\n", i, stLocalvacPqu.u8SatbyPosLut[i]);
	}


	/* write metadata for pqu read */
	ret = mtk_pq_common_write_metadata_addr(pqu_buf,
		EN_PQ_METATAG_PQU_LOCALVAC_TAG, &stLocalvacPqu);
	if (ret) {
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR,
			" write EN_PQ_METATAG_PQU_LOCALVAC_TAG Failed, ret = %d\n", ret);
		return -EFAULT;
	}

	return 0;
}

/* Sony modification start */
static int mtk_pqd_prepare_param_meta(
	struct mtk_pq_device *pq_dev, int fd, __u32 win_id)
{
/* Sony modification end */
	int ret = 0;
	int meta_fd = 0;
	struct meta_buffer pqhal_buf = {0};
	struct meta_buffer pqu_buf = {0};

	if ((!pq_dev)) {
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR, "pq_dev == NULL\n");
		return -ENOMEM;
	}

	meta_fd = fd;

	if (pq_dev->param_dma_info.valid == true)
		mtk_pq_common_put_dma_buf(&pq_dev->param_dma_info);

	pq_dev->param_dma_info.fd = meta_fd;
	STI_PQ_LOG(STI_PQ_LOG_LEVEL_DBG, "stream meta fd = %d\n",
		pq_dev->param_dma_info.fd);

	ret = mtk_pq_common_get_dma_buf(pq_dev, &pq_dev->param_dma_info);
	if (ret) {
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR, "get stream meta buf fail\n");
		return ret;
	}

	//read buffer
	pqhal_buf.paddr = (unsigned char *)pq_dev->param_dma_info.va;
	pqhal_buf.size = (unsigned int)pq_dev->param_dma_info.size;
	//write buffer
	pqu_buf.paddr = (unsigned char *)pq_dev->pq_param_dma_info.va;
	pqu_buf.size = (unsigned int)pq_dev->pq_param_dma_info.size;

	STI_PQ_LOG(STI_PQ_LOG_LEVEL_DBG, "read:va:0x%llx, size:0x%llx,",
		(unsigned long long)pq_dev->param_dma_info.va,
		(unsigned long long)pq_dev->param_dma_info.size);
	STI_PQ_LOG(STI_PQ_LOG_LEVEL_DBG, "write:va:0x%llx, pa:0x%llx,, size:0x%llx,",
		(unsigned long long)pq_dev->pq_param_dma_info.va,
		(unsigned long long)pq_dev->pq_param_dma_info.pa,
		(unsigned long long)pq_dev->pq_param_dma_info.size);

	/* Sony modification start */
	ret = mtk_pqd_SetPQCustomParam(&pqu_buf, &pqhal_buf, win_id);
	if (ret) {
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR, "mtk_pqd_SetPQCustomParam Failed, ret = %d\n", ret);
		// return -EFAULT; //  Fix after
	}
	/* Sony modification end */
	ret = _mtk_pqd_SetPQParam(&pqu_buf, &pqhal_buf);
	if (ret) {
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR, "_mtk_pqd_SetPQParam Failed, ret = %d\n", ret);
		return -EFAULT;
	}

	ret = _mtk_pqd_SetLocalHSY(&pqu_buf, &pqhal_buf);
	if (ret) {
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR, "_mtk_pqd_SetLocalHSY Failed, ret = %d\n", ret);
		return -EFAULT;
	}

	ret = _mtk_pqd_SetLocalVAC(&pqu_buf, &pqhal_buf);
	if (ret) {
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR, "_mtk_pqd_SetLocalVAC Failed, ret = %d\n", ret);
		return -EFAULT;
	}

	ret = _mtk_pqd_SetGCEParam(&pqu_buf, &pqhal_buf);
	if (ret) {
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR, "_mtk_pqd_SetGCEParam Failed, ret = %d\n", ret);
		return -EFAULT;
	}

	if (pq_dev->param_dma_info.valid == true)
		mtk_pq_common_put_dma_buf(&pq_dev->param_dma_info);

	return ret;
}

int mtk_pqd_SetPQParam(struct mtk_pq_device *pq_dev, struct st_pqd_info *pqd_info, void *ctrl,
	void *pq_va_addr, void *pq_pa_addr, __u32 pq_bus_buf_size)
{
	struct callback_info pqparam_callback_info = {0};
	struct v4l2_pq_pqparam table = {0};
	struct msg_pqparam_info msg_info = {0};
	int ret = 0;

	if ((!pqd_info) || (!ctrl) || (!pq_dev)) {
		STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR, "Invalid input\n");
		return -EFAULT;
	}

	memset(&table, 0, sizeof(struct v4l2_pq_pqparam));
	memset(&msg_info, 0, sizeof(struct msg_pqparam_info));
	memcpy(&table, ctrl, sizeof(struct v4l2_pq_pqparam));

	//Get table info
	STI_PQ_LOG(STI_PQ_LOG_LEVEL_DBG,
		"win_id:%d, fd:%d\n", table.win_id, table.fd);

	/* Sony modification start */
	//R/W buffer
	mtk_pqd_prepare_param_meta(pq_dev, table.fd, table.win_id);
	/* Sony modification end */

	STI_PQ_LOG(STI_PQ_LOG_LEVEL_DBG, "va:0x%llx, pa:0x%llx, size:0x%llx",
		(unsigned long long)pq_dev->pq_param_dma_info.va,
		(unsigned long long)pq_dev->pq_param_dma_info.pa,
		(unsigned long long)pq_dev->pq_param_dma_info.size);

	msg_info.win_id = (__u8)table.win_id;
	msg_info.va = (__u64)pq_dev->pq_param_dma_info.va;
	msg_info.pa = (__u64)pq_dev->pq_param_dma_info.pa;
	msg_info.da = (__u64)pq_dev->pq_param_dma_info.pa;
	msg_info.size = (__u64)pq_dev->pq_param_dma_info.size;

	STI_PQ_LOG(STI_PQ_LOG_LEVEL_DBG, "[PQDD][PQPARAM][%d][%#llx][%#llx][%#llx]\n",
		table.win_id, msg_info.va, msg_info.pa, msg_info.size);

	if (bPquEnable) {
		dma_sync_single_for_device(pq_dev->dev,
			pq_dev->pq_param_dma_info.pa,
			pq_dev->pq_param_dma_info.size,
			DMA_TO_DEVICE);
		ret = pqu_video_pqparam_update(&msg_info, &pqparam_callback_info);
		if (ret == -ENODEV) {
			memcpy(&_pqparam_msg_info[_CB_INC(_pqparam_count)],
				&msg_info,
				sizeof(struct msg_pqparam_info));
			STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR,
				"pqu_video_pqparam_update register ready cb\n");
			ret = fw_ext_command_register_notify_ready_callback(0,
				_ready_cb_pqu_video_pqparam_update);
		} else if (ret != 0) {
			STI_PQ_LOG(STI_PQ_LOG_LEVEL_ERROR,
				"pqu_video_pqparam_update fail (ret=%d)\n", ret);
		}
	}
	else
		pqu_msg_send(PQU_MSG_SEND_PQPARAM, (void *)&msg_info);
	return 0;
}

//////////////////////////////////////////////////////get ctrl/////////////////

int mtk_pqd_GetPointToPoint(
	struct st_pqd_info *pqd_info, __s32 *ptp_enable)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ptp_enable);

	return 0;
}

int mtk_pqd_GetGameModeStatus(
	struct st_pqd_info *pqd_info, __s32 *game_enable)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(game_enable);

	return 0;
}


int mtk_pqd_GetDualViewState(
	struct st_pqd_info *pqd_info, __s32 *dual_view_state)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(dual_view_state);

	return 0;
}

int mtk_pqd_GetZeroFrameMode(struct st_pqd_info *pqd_info,
	__s32 *zero_frame_mode)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(zero_frame_mode);

	return 0;
}

//////////////////////////////////////////////////////get extern ctrl//////////

int mtk_pqd_GetRFBLMode(struct st_pqd_info *pqd_info,
	void *ctrl)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ctrl);

	return 0;
}

int mtk_pqd_GetDPUStatus(struct st_pqd_info *pqd_info,
	void *ctrl)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ctrl);

	return 0;
}

int mtk_pqd_ReadPQCmd(struct st_pqd_info *pqd_info,
	void *ctrl)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ctrl);

	return 0;
}

int mtk_pqd_GetSWDRInfo(struct st_pqd_info *pqd_info,
	void *ctrl)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ctrl);

	return 0;
}

int mtk_pqd_GetVideoDelayTime(struct st_pqd_info *pqd_info,
	void *ctrl)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ctrl);

	return 0;
}

int mtk_pqd_GetPQCaps(struct st_pqd_info *pqd_info,
	void *ctrl,
	struct mtk_pq_platform_device *pqdev)
{
	struct v4l2_pq_cap_info *pq_cap_info = NULL;
	bool pr_support = FALSE;

	UNUSED_PARA(pqd_info);

	if (ctrl == NULL) {
		PQ_CHECK_NULLPTR();
		return -EPERM;
	}

	if (pqdev == NULL) {
		PQ_CHECK_NULLPTR();
		return -EPERM;
	}

	mtk_pq_dv_get_pr_cap(pqdev, &pr_support);

	pq_cap_info = (struct v4l2_pq_cap_info *)ctrl;
	pq_cap_info->bDvPD_Supported = pr_support;

	STI_PQ_LOG(STI_PQ_LOG_LEVEL_DBG, "get PD support = %d\n", pq_cap_info->bDvPD_Supported);

	return 0;
}

int mtk_pqd_GetPQVersion(struct st_pqd_info *pqd_info,
	void *ctrl)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ctrl);

	return 0;
}

int mtk_pqd_GetHSYGrule(struct st_pqd_info *pqd_info,
	void *ctrl)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ctrl);

	return 0;
}

int mtk_pqd_GetFBLStatus(struct st_pqd_info *pqd_info,
	void *ctrl)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ctrl);

	return 0;
}

int mtk_pqd_GetIPHistogram(__u16 dev_indx, struct st_pqd_info *pqd_info, void *ctrl,
	void *pq_pa_addr, void *pq_va_addr, __u32 pq_bus_buf_size)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ctrl);
	UNUSED_PARA(pq_pa_addr);
	UNUSED_PARA(pq_va_addr);
	UNUSED_PARA(pq_bus_buf_size);

	return 0;
}

int mtk_pqd_ACE_GetHSYSetting(struct st_pqd_info *pqd_info,
	void *ctrl)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ctrl);

	return 0;
}

int mtk_pqd_ACE_GetHSYRange(struct st_pqd_info *pqd_info,
	void *ctrl)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ctrl);

	return 0;
}

int mtk_pqd_ACE_GetLumaInfo(struct st_pqd_info *pqd_info,
	void *ctrl)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ctrl);

	return 0;
}

int mtk_pqd_ACE_GetChromaInfo(struct st_pqd_info *pqd_info,
	void *ctrl)
{
	UNUSED_PARA(pqd_info);
	UNUSED_PARA(ctrl);

	return 0;
}

int mtk_pqd_Open(struct st_pqd_info *pqd_info)
{
	if (!pqd_info)
		return -EFAULT;

	STI_PQ_LOG(STI_PQ_LOG_LEVEL_ENHANCE, "PQD open\n");

	return 0;
}

int mtk_pqd_Close(struct st_pqd_info *pqd_info)
{
	if (!pqd_info)
		return -EFAULT;

	STI_PQ_LOG(STI_PQ_LOG_LEVEL_ENHANCE, "PQD close\n");
	//todo
	return 0;
}

int mtk_pqd_SetInputSource(struct st_pqd_info *pqd_info,
	__u8 u8Input)
{
	if (!pqd_info)
		return -EFAULT;

	pqd_info->pqd_input_source = u8Input;
	return 0;
}

int mtk_pqd_SetPixFmtIn(struct st_pqd_info *pqd_info,
	struct v4l2_pix_format_mplane *pix)
{
	if ((!pqd_info) || (!pix))
		return -EFAULT;

	STI_PQ_LOG(STI_PQ_LOG_LEVEL_ENHANCE, "PQD pix format in\n");

	//todo
	return 0;
}

int mtk_pqd_SetPixFmtOut(struct st_pqd_info *pqd_info,
	struct v4l2_pix_format_mplane *pix)
{
	if ((!pqd_info) || (!pix))
		return -EFAULT;

	STI_PQ_LOG(STI_PQ_LOG_LEVEL_ENHANCE, "PQD pix format out\n");

	//todo
	return 0;
}


// stream on
int mtk_pqd_StreamOn(struct st_pqd_info *pqd_info)
{
	if (!pqd_info)
		return -EFAULT;

	STI_PQ_LOG(STI_PQ_LOG_LEVEL_ENHANCE, "PQD pix stream on\n");

	//todo
	return 0;
}

// stream off
int mtk_pqd_StreamOff(struct st_pqd_info *pqd_info)
{
	if (!pqd_info)
		return -EFAULT;

	STI_PQ_LOG(STI_PQ_LOG_LEVEL_ENHANCE, "PQD stream off\n");

	//todo
	return 0;
}

