/* * Copyright (c) Hisilicon Technologies Co., Ltd. 2019-2020. All rights reserved. * Description : tvd mpi-part * Author : sdk * Create : 2019/11/21 */ #include #include #include #include #include #include "soc_log.h" #include "td_type.h" #include "mpi_tvd_ext.h" #include "mpi_stat_ext.h" #ifdef __cplusplus #if __cplusplus extern "C" { #endif #endif /* __cplusplus */ static ext_mpi_tvd_ctx g_tvd_mpi_ctx = { TD_FALSE, -1 }; pthread_mutex_t g_sttvdmutex = PTHREAD_MUTEX_INITIALIZER; #define ext_tvd_lock() (void)pthread_mutex_lock(&g_sttvdmutex) #define ext_tvd_unlock() (void)pthread_mutex_unlock(&g_sttvdmutex) td_s32 ext_mpi_tvd_init(td_void) { td_s32 fd = -1; ext_mpi_tvd_ctx *ctx = tvd_mpi_get_ctx(); ext_tvd_lock(); if (ctx->inited == TD_TRUE) { soc_log_err("TVD has already inited, fd: %d\n", fd); ext_tvd_unlock(); return TD_SUCCESS; } fd = open("/dev/soc_tvd", O_RDWR | O_NONBLOCK); if (fd < 0) { soc_log_err("open tvd device failed\n"); ext_tvd_unlock(); return TD_FAILURE; } ctx->fd = fd; ctx->inited = TD_TRUE; ext_tvd_unlock(); return TD_SUCCESS; } td_s32 ext_mpi_tvd_de_init(td_void) { td_s32 ret; ext_mpi_tvd_ctx *ctx = tvd_mpi_get_ctx(); ext_tvd_lock(); if (ctx->inited == TD_FALSE) { soc_log_err("TVD has not inited\n"); ext_tvd_unlock(); return TD_SUCCESS; } ctx->inited = TD_FALSE; ret = close(ctx->fd); ext_tvd_unlock(); return ret; } td_s32 ext_mpi_tvd_connect(ext_drv_tvd_src_attr_in *src_attr) { td_s32 ret = TD_SUCCESS; ext_mpi_tvd_ctx *ctx = tvd_mpi_get_ctx(); soc_dbg_func_enter(); if (src_attr == NULL) { soc_log_err("NULL pointer\n"); return TD_FAILURE; } if (g_tvd_mpi_ctx.inited != TD_TRUE) { return TD_FAILURE; } (td_void)ext_mpi_stat_event(EXT_STAT_EVENT_CONNECT, 0); if ((src_attr->type != EXT_DRV_SOURCE_ATV) && (src_attr->type != EXT_DRV_SOURCE_CVBS)) { soc_log_err("source type set from user is invaild\n"); return TD_FAILURE; } ret = ioctl(ctx->fd, IOC_TVD_CONNECT, src_attr); if (ret != TD_SUCCESS) { soc_log_err("ioctl connect failed\n"); return ret; } soc_dbg_func_exit(); return TD_SUCCESS; } td_s32 ext_mpi_tvd_dis_connect(td_void) { td_s32 ret; ext_mpi_tvd_ctx *ctx = tvd_mpi_get_ctx(); if (g_tvd_mpi_ctx.inited != TD_TRUE) { return TD_FAILURE; } ret = ioctl(ctx->fd, IOC_TVD_DISCONNECT); if (ret != TD_SUCCESS) { soc_log_err("ioctl disconnect failed\n"); return ret; } return TD_SUCCESS; } td_s32 ext_mpi_tvd_get_signal_status(ext_drv_sig_status *signal_status) { td_s32 ret = TD_SUCCESS; static ext_drv_sig_status sig_status = EXT_DRV_SIG_NO_SIGNAL; ext_mpi_tvd_ctx *ctx = tvd_mpi_get_ctx(); if (signal_status == NULL) { soc_log_err("NULL pointer\n"); return TD_FAILURE; } *signal_status = EXT_DRV_SIG_NO_SIGNAL; if (g_tvd_mpi_ctx.inited != TD_TRUE) { return TD_FAILURE; } ret = ioctl(ctx->fd, IOC_TVD_G_STATUS, signal_status); if ((sig_status != EXT_DRV_SIG_SUPPORT) && (*signal_status == EXT_DRV_SIG_SUPPORT)) { ext_mpi_stat_event(EXT_STAT_EVENT_LOCKED, 0); } sig_status = *signal_status; return ret; } td_s32 ext_mpi_tvd_get_std_timing_info(ext_drv_tvd_timing_info *timing_info) { td_s32 ret = TD_SUCCESS; ext_mpi_tvd_ctx *ctx = tvd_mpi_get_ctx(); if (timing_info == NULL) { soc_log_err("NULL pointer\n"); return TD_FAILURE; } if (g_tvd_mpi_ctx.inited != TD_TRUE) { return TD_FAILURE; } ret = ioctl(ctx->fd, IOC_TVD_G_TIMING_INFO, timing_info); return ret; } td_s32 ext_mpi_tvd_set_color_system(ext_drv_color_sys color_sys) { td_s32 ret; ext_mpi_tvd_ctx *ctx = tvd_mpi_get_ctx(); if (g_tvd_mpi_ctx.inited != TD_TRUE) { return TD_FAILURE; } if (color_sys >= EXT_DRV_COLOR_SYS_MAX) { soc_log_err("color_sys set by user is inavild\n"); return TD_FAILURE; } ret = ioctl(ctx->fd, IOC_TVD_S_COLORSYS, &color_sys); return ret; } td_s32 ext_mpi_tvd_get_color_system(ext_drv_color_sys *color_sys) { td_s32 ret = TD_SUCCESS; ext_mpi_tvd_ctx *ctx = tvd_mpi_get_ctx(); if (color_sys == NULL) { soc_log_err("NULL pointer\n"); return TD_FAILURE; } *color_sys = EXT_DRV_COLOR_SYS_MAX; if (g_tvd_mpi_ctx.inited != TD_TRUE) { return TD_FAILURE; } ret = ioctl(ctx->fd, IOC_TVD_G_COLORSYS, color_sys); return ret; } td_s32 ext_mpi_tvd_get_signal_lock(td_bool *lock) { td_s32 ret = TD_SUCCESS; ext_mpi_tvd_ctx *ctx = tvd_mpi_get_ctx(); if (lock == NULL) { soc_log_err("NULL pointer\n"); return TD_FAILURE; } *lock = TD_FALSE; if (g_tvd_mpi_ctx.inited != TD_TRUE) { return TD_FAILURE; } ret = ioctl(ctx->fd, IOC_TVD_G_SIGNAL_LOCK, lock); return ret; } td_s32 ext_mpi_tvd_get_noise_value(td_u32 *value) { td_s32 ret = TD_SUCCESS; ext_mpi_tvd_ctx *ctx = tvd_mpi_get_ctx(); if (value == NULL) { soc_log_err("NULL pointer\n"); return TD_FAILURE; } *value = 0xFF; if (g_tvd_mpi_ctx.inited != TD_TRUE) { return TD_FAILURE; } ret = ioctl(ctx->fd, IOC_TVD_G_NOISE_LEVEL, value); return ret; } td_s32 ext_mpi_tvd_get_macrovision_status(td_bool *status) { td_s32 ret = TD_SUCCESS; ext_mpi_tvd_ctx *ctx = tvd_mpi_get_ctx(); if (status == NULL) { soc_log_err("NULL pointer\n"); return TD_FAILURE; } *status = TD_FALSE; if (g_tvd_mpi_ctx.inited != TD_TRUE) { return TD_FAILURE; } ret = ioctl(ctx->fd, IOC_TVD_G_MARCOVISION, status); return ret; } td_s32 ext_mpi_tvd_get_nstd_info(ext_drv_video_nonstd_info *nstd_info) { td_s32 ret = TD_SUCCESS; ext_mpi_tvd_ctx *ctx = tvd_mpi_get_ctx(); if (nstd_info == NULL) { soc_log_err("NULL pointer\n"); return TD_FAILURE; } if (g_tvd_mpi_ctx.inited != TD_TRUE) { return TD_FAILURE; } ret = ioctl(ctx->fd, IOC_TVD_G_NSTD_INFO, nstd_info); return ret; } td_s32 ext_mpi_tvd_get_range(ext_drv_tvd_pos_type type, ext_range *range) { td_s32 ret = TD_SUCCESS; ext_mpi_tvd_ctx *ctx = tvd_mpi_get_ctx(); if (range == NULL) { soc_log_err("NULL pointer\n"); return TD_FAILURE; } if (g_tvd_mpi_ctx.inited != TD_TRUE) { return TD_FAILURE; } if (type >= EXT_DRV_TVD_POS_MAX) { soc_log_err("type set by user is inavild\n"); return TD_FAILURE; } if (type == EXT_DRV_TVD_POS_H) { ret = ioctl(ctx->fd, IOC_TVD_G_H_RANGE, range); } else { ret = ioctl(ctx->fd, IOC_TVD_G_V_RANGE, range); } return ret; } td_s32 ext_mpi_tvd_get_position(ext_drv_tvd_pos_type type, td_u32 *pos) { td_s32 ret = TD_SUCCESS; ext_mpi_tvd_ctx *ctx = tvd_mpi_get_ctx(); if (pos == NULL) { soc_log_err("NULL pointer\n"); return TD_FAILURE; } if (g_tvd_mpi_ctx.inited != TD_TRUE) { return TD_FAILURE; } if (type >= EXT_DRV_TVD_POS_MAX) { soc_log_err("type set by user is inavild\n"); return TD_FAILURE; } if (type == EXT_DRV_TVD_POS_H) { ret = ioctl(ctx->fd, IOC_TVD_G_H_POS, pos); } else { ret = ioctl(ctx->fd, IOC_TVD_G_V_POS, pos); } return ret; } td_s32 ext_mpi_tvd_set_position(ext_drv_tvd_pos_type type, td_u32 pos) { td_s32 ret; ext_mpi_tvd_ctx *ctx = tvd_mpi_get_ctx(); if (g_tvd_mpi_ctx.inited != TD_TRUE) { return TD_FAILURE; } if (type >= EXT_DRV_TVD_POS_MAX) { soc_log_err("type set by user is inavild\n"); return TD_FAILURE; } if (type == EXT_DRV_TVD_POS_H) { ret = ioctl(ctx->fd, IOC_TVD_S_H_POS, &pos); } else { ret = ioctl(ctx->fd, IOC_TVD_S_V_POS, &pos); } return ret; } td_s32 ext_mpi_tvd_get_offline_status(const ext_drv_tvd_src_attr_in *src_attr, td_bool *status) { td_s32 ret = TD_SUCCESS; tvd_offline_param offline_param; ext_mpi_tvd_ctx *ctx = tvd_mpi_get_ctx(); if (src_attr == NULL || status == NULL) { soc_log_err("NULL pointer\n"); return TD_FAILURE; } *status = TD_FALSE; if (g_tvd_mpi_ctx.inited != TD_TRUE) { return TD_FAILURE; } if (src_attr->type >= EXT_DRV_SOURCE_MAX) { soc_log_err("type set by user is inavild\n"); return TD_FAILURE; } offline_param.src_attr.type = src_attr->type; offline_param.src_attr.index = src_attr->index; ret = ioctl(ctx->fd, IOC_TVD_G_OFFLINE_STATUS, &offline_param); *status = offline_param.sig_exist; return ret; } td_s32 ext_mpi_tvd_set_pedestal(td_bool enable) { td_s32 ret; ext_mpi_tvd_ctx *ctx = tvd_mpi_get_ctx(); if (g_tvd_mpi_ctx.inited != TD_TRUE) { return TD_FAILURE; } ret = ioctl(ctx->fd, IOC_TVD_S_PEDSTAL, &enable); return ret; } td_s32 ext_mpi_tvd_set_color_system_filter(ext_drv_tvd_sys_filter *sys_filter) { td_s32 ret = TD_SUCCESS; ext_mpi_tvd_ctx *ctx = tvd_mpi_get_ctx(); if (sys_filter == NULL) { soc_log_err("NULL pointer\n"); return TD_FAILURE; } if (g_tvd_mpi_ctx.inited != TD_TRUE) { return TD_FAILURE; } ret = ioctl(ctx->fd, IOC_TVD_S_COLORFILTER, sys_filter); return ret; } td_s32 ext_mpi_tvd_get_color_system_filter(ext_drv_tvd_sys_filter *sys_filter) { td_s32 ret = TD_SUCCESS; ext_mpi_tvd_ctx *ctx = tvd_mpi_get_ctx(); if (sys_filter == NULL) { soc_log_err("NULL pointer\n"); return TD_FAILURE; } if (g_tvd_mpi_ctx.inited != TD_TRUE) { return TD_FAILURE; } ret = ioctl(ctx->fd, IOC_TVD_G_COLORFILTER, sys_filter); return ret; } td_s32 ext_mpi_tvd_set_comb_filter_mode(ext_drv_tvd_comb_mode mode) { td_s32 ret; ext_mpi_tvd_ctx *ctx = tvd_mpi_get_ctx(); if (g_tvd_mpi_ctx.inited != TD_TRUE) { return TD_FAILURE; } if (mode >= EXT_DRV_TVD_COMB_MAX) { soc_log_err("mode set by user is inavild\n"); return TD_FAILURE; } ret = ioctl(ctx->fd, IOC_TVD_S_COMB_MODE, &mode); return ret; } td_s32 ext_mpi_tvd_get_line_status(td_bool *is625) { td_s32 ret = TD_SUCCESS; ext_mpi_tvd_ctx *ctx = tvd_mpi_get_ctx(); if (is625 == NULL) { soc_log_err("NULL pointer\n"); return TD_FAILURE; } *is625 = TD_FALSE; if (g_tvd_mpi_ctx.inited != TD_TRUE) { return TD_FAILURE; } ret = ioctl(ctx->fd, IOC_TVD_G_625_MODE, is625); return ret; } td_s32 ext_mpi_tvd_set_work_mode(ext_drv_tvd_work_mode work_mode) { td_s32 ret; ext_mpi_tvd_ctx *ctx = tvd_mpi_get_ctx(); if (g_tvd_mpi_ctx.inited != TD_TRUE) { return TD_FAILURE; } if (work_mode >= EXT_DRV_TVD_WORK_MODE_MAX) { soc_log_err("work_mode set by user is inavild\n"); return TD_FAILURE; } ret = ioctl(ctx->fd, IOC_TVD_S_WORK_MODE, &work_mode); return ret; } td_s32 ext_mpi_tvd_get_capability(ext_drv_tvd_capability *capability) { td_s32 ret = TD_SUCCESS; ext_mpi_tvd_ctx *ctx = tvd_mpi_get_ctx(); if (capability == NULL) { soc_log_err("NULL pointer\n"); return TD_FAILURE; } if (g_tvd_mpi_ctx.inited != TD_TRUE) { return TD_FAILURE; } ret = ioctl(ctx->fd, IOC_TVD_G_CAPABILITY, capability); return ret; } td_s32 ext_mpi_tvd_set_ink_mode(tvd_inkmode_cmd_type type, tvd_inkmode ink_mode) { td_s32 ret; ext_mpi_tvd_ctx *ctx = tvd_mpi_get_ctx(); tvd_ink_mode_attr mode_attr; if (g_tvd_mpi_ctx.inited != TD_TRUE) { return TD_FAILURE; } if (ink_mode >= TVD_INKMODE_MAX) { soc_log_err("ink_mode set by user is inavild\n"); return TD_FAILURE; } if (type >= TVD_INKMODE_CMD_TYPE_MAX) { soc_log_err("type set by user is inavild\n"); return TD_FAILURE; } mode_attr.cmd_type = type; mode_attr.ink_mode = ink_mode; ret = ioctl(ctx->fd, IOC_TVD_S_INK_MODE, &mode_attr); return ret; } td_s32 ext_mpi_tvd_get_ink_mode(tvd_inkmode_cmd_type type, tvd_inkmode *ink_mode) { td_s32 ret = TD_SUCCESS; ext_mpi_tvd_ctx *ctx = tvd_mpi_get_ctx(); tvd_ink_mode_attr mode_attr; if (ink_mode == NULL) { soc_log_err("NULL pointer\n"); return TD_FAILURE; } if (g_tvd_mpi_ctx.inited != TD_TRUE) { return TD_FAILURE; } if (type >= TVD_INKMODE_CMD_TYPE_MAX) { soc_log_err("type set by user is inavild\n"); return TD_FAILURE; } ret = ioctl(ctx->fd, IOC_TVD_G_INK_MODE, &mode_attr); *ink_mode = mode_attr.ink_mode; return ret; } td_s32 ext_mpi_tvd_set_pq_debug_cfg(td_u32 offset, td_u32 para_value) { td_s32 ret; ext_mpi_tvd_ctx *ctx = tvd_mpi_get_ctx(); tvd_pq_debug pq_debug; if (g_tvd_mpi_ctx.inited != TD_TRUE) { return TD_FAILURE; } pq_debug.offset = offset; pq_debug.para_value = para_value; ret = ioctl(ctx->fd, IOC_TVD_S_PQ_DEBUG, &pq_debug); return ret; } td_s32 ext_mpi_tvd_get_pq_debug_cfg(td_u32 offset, td_u32 *para_value) { td_s32 ret = TD_SUCCESS; ext_mpi_tvd_ctx *ctx = tvd_mpi_get_ctx(); tvd_pq_debug pq_debug; if (para_value == NULL) { soc_log_err("NULL pointer\n"); return TD_FAILURE; } if (g_tvd_mpi_ctx.inited != TD_TRUE) { return TD_FAILURE; } pq_debug.offset = offset; ret = ioctl(ctx->fd, IOC_TVD_G_PQ_DEBUG, &pq_debug); *para_value = pq_debug.para_value; return ret; } #ifdef __cplusplus #if __cplusplus } #endif #endif /* __cplusplus */