You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

584 lines
14 KiB

/*
* Copyright (c) Hisilicon Technologies Co., Ltd. 2019-2020. All rights reserved.
* Description : tvd mpi-part
* Author : sdk
* Create : 2019/11/21
*/
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <pthread.h>
#include <sys/stat.h>
#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 */