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.

441 lines
10 KiB

/*
* Copyright (c) Hisilicon Technologies Co., Ltd. 2019-2020. All rights reserved.
* Description : hddec
* Author : sdk
* Create : 2019/11/21
*/
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <pthread.h>
#include "soc_log.h"
#include "mpi_hddec_ext.h"
#include "drv_ioctl_hddec.h"
#include "mpi_stat_ext.h"
static td_s32 g_hddec_dev_fd = -1;
static pthread_mutex_t g_hddec_mutex = PTHREAD_MUTEX_INITIALIZER;
#define ext_hddec_lock() (td_void)pthread_mutex_lock(&g_hddec_mutex)
#define ext_hddec_unlock() (td_void)pthread_mutex_unlock(&g_hddec_mutex)
#define check_hddec_init(ret) \
do { \
ext_hddec_lock(); \
if (g_hddec_dev_fd < 0) { \
soc_log_err("please init firstly.\n"); \
(ret) = TD_FAILURE; \
} \
ext_hddec_unlock(); \
} while (0)
/* HDDEC初始化 */
td_s32 ext_mpi_hddec_init(td_void)
{
struct stat stat_info;
ext_hddec_lock();
/* already opened in the process */
if (g_hddec_dev_fd > 0) {
ext_hddec_unlock();
return TD_SUCCESS;
}
g_hddec_dev_fd = open("/dev/soc_hddec", O_RDWR | O_NONBLOCK, 0);
if (g_hddec_dev_fd < 0) {
soc_log_err("open HDDEC err.\n");
ext_hddec_unlock();
return TD_FAILURE;
}
if (stat("/dev/soc_hddec", &stat_info) != 0) {
soc_log_err("HDDEC is not exist.\n");
close(g_hddec_dev_fd);
g_hddec_dev_fd = -1;
ext_hddec_unlock();
return TD_FAILURE;
}
if (!S_ISCHR(stat_info.st_mode)) {
soc_log_err("HDDEC is not device.\n");
close(g_hddec_dev_fd);
g_hddec_dev_fd = -1;
ext_hddec_unlock();
return TD_FAILURE;
}
ext_hddec_unlock();
return TD_SUCCESS;
}
/* HDDEC去初始化 */
td_s32 ext_mpi_hddec_de_init(td_void)
{
ext_hddec_lock();
if (g_hddec_dev_fd < 0) {
ext_hddec_unlock();
return TD_SUCCESS;
}
close(g_hddec_dev_fd);
g_hddec_dev_fd = -1;
ext_hddec_unlock();
return TD_SUCCESS;
}
/* 信源连接 */
td_s32 ext_mpi_hddec_connect(const ext_drv_hddec_src_attr *src_attr)
{
td_s32 ret = TD_SUCCESS;
check_hddec_init(ret);
if (ret == TD_FAILURE) {
return TD_FAILURE;
}
ext_mpi_stat_event(EXT_STAT_EVENT_CONNECT, 1);
ret = ioctl(g_hddec_dev_fd, IOC_HDDEC_CONNECT, src_attr);
return ret;
}
/* 断开连接 */
td_s32 ext_mpi_hddec_dis_connect(td_void)
{
td_s32 ret = TD_SUCCESS;
check_hddec_init(ret);
if (ret == TD_FAILURE) {
return TD_FAILURE;
}
ret = ioctl(g_hddec_dev_fd, IOC_HDDEC_DISCONNECT);
return ret;
}
/* 获取离线信源的信号是否存在,阻塞接口 */
td_s32 ext_mpi_hddec_get_offline_status(const ext_drv_hddec_src_attr *src_att, td_bool *exist)
{
td_s32 ret = TD_SUCCESS;
ext_drv_hddec_offline_param offline_param;
if (src_att == NULL) {
soc_log_err("offline is NULL pointer!\n");
return TD_FAILURE;
}
if (exist == NULL) {
soc_log_err("exist_sig is NULL pointer!\n");
return TD_FAILURE;
}
*exist = TD_FALSE;
check_hddec_init(ret);
if (ret == TD_FAILURE) {
return TD_FAILURE;
}
offline_param.src_attr.src_type = src_att->src_type;
offline_param.src_attr.index = src_att->index;
ret = ioctl(g_hddec_dev_fd, IOC_HDDEC_G_OFFLINE_SIG, &offline_param);
if (ret != TD_SUCCESS) {
soc_log_err("get offline param failed\n");
*exist = TD_FALSE;
return ret;
}
*exist = offline_param.exist;
return TD_SUCCESS;
}
/* 检测当前的decode状态 */
td_s32 ext_mpi_hddec_get_signal_status(ext_drv_hddec_signal_status *sig_status)
{
td_s32 ret = TD_SUCCESS;
if (sig_status == NULL) {
soc_log_err("sig_status is NULL pointer.\n");
return TD_FAILURE;
}
*sig_status = EXT_DRV_HDDEC_SIG_NO_SIGNAL;
check_hddec_init(ret);
if (ret == TD_FAILURE) {
return TD_FAILURE;
}
/* if mpi status change from not support to support, check whether send mpi event */
ret = ioctl(g_hddec_dev_fd, IOC_HDDEC_G_SIGNAL_STATUS, sig_status);
return ret;
}
/* 检测当前的decode_timing信息 */
td_s32 ext_mpi_hddec_get_timing_info(ext_drv_hddec_timing_info *timing_info)
{
td_s32 ret = TD_SUCCESS;
check_hddec_init(ret);
if (ret == TD_FAILURE) {
return TD_FAILURE;
}
if (timing_info == TD_NULL) {
soc_log_err("NULL ptr.\n");
return TD_FAILURE;
}
ret = ioctl(g_hddec_dev_fd, IOC_HDDEC_G_TIMING_INFO, timing_info);
return ret;
}
/* 检测当前的decode非标信息 */
td_s32 ext_mpi_hddec_get_non_std_info(ext_drv_hddec_nonstd_info *non_std_info)
{
td_s32 ret = TD_SUCCESS;
check_hddec_init(ret);
if (ret == TD_FAILURE) {
return TD_FAILURE;
}
if (non_std_info == TD_NULL) {
soc_log_err("NULL ptr.\n");
return TD_FAILURE;
}
ret = ioctl(g_hddec_dev_fd, IOC_HDDEC_G_NONSTD_INFO, non_std_info);
return ret;
}
/* 启动自动颜色校正 */
td_s32 ext_mpi_hddec_start_calibrate_color(td_void)
{
td_s32 ret = TD_SUCCESS;
check_hddec_init(ret);
if (ret == TD_FAILURE) {
return TD_FAILURE;
}
ret = ioctl(g_hddec_dev_fd, IOC_HDDEC_START_CALIB);
return ret;
}
/* 获取自动颜色校正状态 */
td_s32 ext_mpi_hddec_get_calibration_status(ext_drv_hddec_color_calib_status *calib_status)
{
td_s32 ret = TD_SUCCESS;
check_hddec_init(ret);
if (ret == TD_FAILURE) {
return TD_FAILURE;
}
if (calib_status == TD_NULL) {
soc_log_err("NULL ptr.\n");
return TD_FAILURE;
}
ret = ioctl(g_hddec_dev_fd, IOC_HDDEC_G_CALIB_INFO, calib_status);
return ret;
}
/* 获取手动设置自动颜色校正参数 */
td_s32 ext_mpi_hddec_get_calibration_param(ext_drv_hddec_color_calib_param *calib_param)
{
td_s32 ret = TD_SUCCESS;
check_hddec_init(ret);
if (ret == TD_FAILURE) {
return TD_FAILURE;
}
if (calib_param == TD_NULL) {
soc_log_err("NULL ptr.\n");
return TD_FAILURE;
}
ret = ioctl(g_hddec_dev_fd, IOC_HDDEC_G_CALIB_PARAM, calib_param);
return ret;
}
/* 手动设置自动颜色校正 */
td_s32 ext_mpi_hddec_set_calibration_param(const ext_drv_hddec_color_calib_param *calib_param)
{
td_s32 ret = TD_SUCCESS;
check_hddec_init(ret);
if (ret == TD_FAILURE) {
return TD_FAILURE;
}
if (calib_param == TD_NULL) {
soc_log_err("NULL ptr.\n");
return TD_FAILURE;
}
ret = ioctl(g_hddec_dev_fd, IOC_HDDEC_S_CALIB_PARAM, calib_param);
return ret;
}
/* 启动VGA图像自动调整 */
td_s32 ext_mpi_hddec_start_adjust_image_param(td_void)
{
td_s32 ret = TD_SUCCESS;
check_hddec_init(ret);
if (ret == TD_FAILURE) {
return TD_FAILURE;
}
ret = ioctl(g_hddec_dev_fd, IOC_HDDEC_START_ADJUST);
return ret;
}
/* 获取VGA图像自动调整状态 */
td_s32 ext_mpi_hddec_get_adjust_status(ext_drv_hddec_adjust_status *adjust_status)
{
td_s32 ret = TD_SUCCESS;
check_hddec_init(ret);
if (ret == TD_FAILURE) {
return TD_FAILURE;
}
if (adjust_status == TD_NULL) {
soc_log_err("NULL ptr.\n");
return TD_FAILURE;
}
ret = ioctl(g_hddec_dev_fd, IOC_HDDEC_G_ADJUST_INFO, adjust_status);
return ret;
}
/* 获取手动调整可调范围 */
td_s32 ext_mpi_hddec_get_adjust_range(ext_drv_hddec_adjust_type adjust_type, ext_range *range)
{
td_s32 ret = TD_SUCCESS;
ext_drv_hddec_adjust_range adjust_range;
check_hddec_init(ret);
if (ret == TD_FAILURE) {
return TD_FAILURE;
}
if (range == NULL) {
soc_log_err("range is NULL pointer!\n");
return TD_FAILURE;
}
adjust_range.type = adjust_type;
ret = ioctl(g_hddec_dev_fd, IOC_HDDEC_G_ADJUST_RANGE, &adjust_range);
if (ret != TD_SUCCESS) {
soc_log_err("get adjust range failed.\n");
return ret;
}
range->min = adjust_range.range.min;
range->max = adjust_range.range.max;
return TD_SUCCESS;
}
/* 获取调整的参数 */
td_s32 ext_mpi_hddec_get_adjust_param(ext_drv_hddec_adjust_type adjust_type, td_u32 *param)
{
td_s32 ret = TD_SUCCESS;
ext_drv_hddec_adjust_param adjust_param;
check_hddec_init(ret);
if (ret == TD_FAILURE) {
return TD_FAILURE;
}
if (param == NULL) {
soc_log_err("param is NULL pointer!\n");
return TD_FAILURE;
}
adjust_param.type = adjust_type;
ret = ioctl(g_hddec_dev_fd, IOC_HDDEC_G_ADJUST_PARAM, &adjust_param);
if (ret != TD_SUCCESS) {
soc_log_err("get adjust param failed.\n");
return ret;
}
*param = adjust_param.param;
return TD_SUCCESS;
}
/* 设置手动调整参数 */
td_s32 ext_mpi_hddec_set_adjust_param(ext_drv_hddec_adjust_type adjust_type, td_u32 param)
{
td_s32 ret = TD_SUCCESS;
ext_drv_hddec_adjust_param adjust_param;
check_hddec_init(ret);
if (ret == TD_FAILURE) {
return TD_FAILURE;
}
if (adjust_type >= EXT_DRV_HDDEC_ADJUST_TYPE_MAX) {
soc_log_err("adjust is invalid.\n");
return TD_FAILURE;
}
adjust_param.type = adjust_type;
adjust_param.param = param;
ret = ioctl(g_hddec_dev_fd, IOC_HDDEC_S_ADJUST_PARAM, &adjust_param);
return ret;
}
/* 更新edid */
td_s32 ext_mpi_hddec_update_edid(const ext_drv_hddec_edid *edid)
{
td_s32 ret = TD_SUCCESS;
check_hddec_init(ret);
if (ret == TD_FAILURE) {
return TD_FAILURE;
}
ret = ioctl(g_hddec_dev_fd, IOC_HDDEC_U_EDID, edid);
return ret;
}
/* 获取能力信息 */
td_s32 ext_mpi_hddec_get_capability(ext_drv_hddec_capability *capability)
{
td_s32 ret = TD_SUCCESS;
check_hddec_init(ret);
if (ret == TD_FAILURE) {
return TD_FAILURE;
}
if (capability == TD_NULL) {
soc_log_err("NULL ptr.\n");
return TD_FAILURE;
}
ret = ioctl(g_hddec_dev_fd, IOC_HDDEC_G_CAPABILITY, capability);
return ret;
}