当前位置: 首页 > news >正文

RK628F HDMI-IN调试:应用接口使用

RK628F对接RK3588等SOC平台,可以作为HDMI-IN功能使用,应用可以在用户层获取驱动的相关接口信息,例如:颜色格式、色域、颜色空间等等信息,这篇文章简单介绍一下驱动相关的接口,以及应用如何使用对应的接口进行开发。

1.接口介绍

介绍一下RK628F的驱动都支持哪些接口供应用读取使用,RK628F的接口可以分为V4l2标准接口,RK HDMI-IN的私有接口、RK camera的私有接口。一起来看一下这些接口。

1.1 V4L2接口

V4L2的标准接口,基于V4L2的标准框架实现,主要有如下:

1.1.1 VIDIOC_SUBDEV_G_FMT

调用驱动的rk628_csi_get_fmt获取当前输出的分辨率;

static int rk628_csi_get_fmt(struct v4l2_subdev *sd,struct v4l2_subdev_state *sd_state,struct v4l2_subdev_format *format)
{struct rk628_csi *csi = to_csi(sd);......mutex_lock(&csi->confctl_mutex);format->format.code = csi->mbus_fmt_code;format->format.width = ALIGN_DOWN(csi->timings.bt.width, 4);format->format.height = csi->timings.bt.height;format->format.field = csi->timings.bt.interlaced ?V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE;
......
1.1.2 VIDIOC_SUBDEV_S_FMT

设置输出分辨率,用户层一般不用

1.1.3 VIDIOC_SUBDEV_QUERY_DV_TIMINGS

获取当前HDMI-IN的Timings;

static int rk628_csi_query_dv_timings(struct v4l2_subdev *sd,struct v4l2_dv_timings *timings)
{int ret;struct rk628_csi *csi = to_csi(sd);struct v4l2_dv_timings default_timing =V4L2_DV_BT_CEA_640X480P59_94;if (!tx_5v_power_present(sd) || csi->nosignal) {*timings = default_timing;v4l2_info(sd, "%s: not detect 5v, set default timing\n", __func__);return 0;}mutex_lock(&csi->confctl_mutex);ret = rk628_csi_get_detected_timings(sd, timings);mutex_unlock(&csi->confctl_mutex);if (ret)return ret;if (debug)v4l2_print_dv_timings(sd->name, "rk628_csi_query_dv_timings: ",timings, false);if (!v4l2_valid_dv_timings(timings, &rk628_csi_timings_cap, NULL,NULL)) {v4l2_dbg(1, debug, sd, "%s: timings out of range\n", __func__);return -ERANGE;}return 0;
}
1.1.4 VIDIOC_SUBDEV_G_EDID

获取当前的EDID信息;

1.1.5 VIDIOC_SUBDEV_S_EDID

设置EDID,通常设置完会拉一下HPD,重新让信号源输出信号;

1.2 RK HDMI接口

这部分是RK HDMI-IN的私有接口,简要介绍如下:

1.2.1 RKMODULE_GET_HDMI_MODE

获取mode参数,判断当前是否是HDMI-IN的类型,通常HDMI-IN的转接芯片需要返回1即可。

	case RKMODULE_GET_HDMI_MODE:*(int *)arg = RKMODULE_HDMIIN_MODE;break;
1.2.2 RK_HDMIRX_CMD_GET_FPS

读取当前的帧率信息。

1.2.3 RK_HDMIRX_CMD_GET_HDCP_ENC_STATUS

读取当前的驱动的HDCP状态;

1.2.4 RK_HDMIRX_CMD_GET_INPUT_MODE

获取当前的输入模式,判断是否是DVI模式

1.2.5 RK_HDMIRX_CMD_GET_SIGNAL_STABLE_STATUS

获取判断当前的信号锁定状态;

1.2.6 RK_HDMIRX_CMD_GET_SCAN_MODE

获取当前HDMI-RX的scan mode,即隔行还是逐行信号;

1.2.7 RK_HDMIRX_CMD_GET_COLOR_RANGE

获取当前hdmi-rx的色域信息

1.2.8 RK_HDMIRX_CMD_GET_COLOR_SPACE

获取当前hdmi-rx的颜色空间

1.2.9 RK_HDMIRX_CMD_GET_EDID_VERSION

获取当前的EDID版本;

1.2.10 RK_HDMIRX_CMD_SET_COLOR_RANGE

设置颜色空间转换方式;

1.2.11 RK_HDMIRX_CMD_SET_EDID_VERSION

设置EDID版本;

1.3 RK camera接口

这部分是RK camera相关的私有接口,主要介绍如下:

1.3.1 RKMODULE_GET_MODULE_INFO

获取当前的模块信息,注意module name的匹配与index的设置,需要在dts配置。

module name对接TV框架时候需要用到

1.3.2 RKMODULE_GET_CSI_DSI_INFO

获取判断当前输出是CSI还是DSI,一般驱动使用,用户无用

1.3.3 RKMODULE_GET_DSI_MODE

获取判断DSI模式的类别,有video mode跟command mode,对于用户没用

2.应用示例

以下以一个简要的示例介绍一下用户如何使用这些接口来获取驱动的相关信息。

1.获取找到当前的节点,RK628F的设备节点是/dev/v4l-subdev,需要根据接口RKMODULE_GET_HDMI_MODE来获取判断当前的节点是否为hdmi-in的节点,也可以通过RKMODULE_GET_MODULE_INFO接口获取设备名称来判断。

2.参考示例,可以根据VIDIOC_G_CTRL接口来获取当前驱动的拔插状态,在设备插入状态下载获取相关的信息。

3.执行相关ioctl获取驱动的信息。

4.获取完毕,关闭文件节点。

#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <string.h>
#include <linux/videodev2.h>
#include <linux/v4l2-subdev.h>#define RKMODULE_GET_HDMI_MODE       \_IOR('V', BASE_VIDIOC_PRIVATE + 34, __u32)#define RK_HDMIRX_CMD_GET_FPS \_IOR('V', BASE_VIDIOC_PRIVATE + 0, int)#define RK_HDMIRX_CMD_GET_SIGNAL_STABLE_STATUS \_IOR('V', BASE_VIDIOC_PRIVATE + 1, int)#define RK_HDMIRX_CMD_GET_COLOR_SPACE \_IOR('V', BASE_VIDIOC_PRIVATE + 10, int)const int kMaxDevicePathLen = 256;
const char* kDevicePath = "/dev/";
const char kPrefix[] = "v4l-subdev";
const int kPrefixLen = sizeof(kPrefix) - 1;
const int kDevicePrefixLen = sizeof(kDevicePath) + kPrefixLen + 1;
char kV4l2DevicePath[kMaxDevicePathLen];
int mipifd = 0;static const char *bus_color_space_str[8] = {"xvYCC601", "xvYCC709", "sYCC601", "Adobe_YCC601","Adobe_RGB", "BT2020_YcCbcCrc", "BT2020_RGB_OR_YCbCr", "RGB"
};int find_mipi_fd()
{DIR *devdir;struct dirent* de;int videofd;int ret;devdir = opendir(kDevicePath);if(devdir == 0) {printf("%s: cannot open %s!\n", __FUNCTION__, kDevicePath);return -1;}while ((de = readdir(devdir)) != 0) {if (!strncmp(kPrefix, de->d_name, kPrefixLen)) {printf("found %s\n", de->d_name);snprintf(kV4l2DevicePath, kMaxDevicePathLen,"%s%s", kDevicePath, de->d_name);videofd = open(kV4l2DevicePath, O_RDWR);if (videofd < 0){printf("[%s %d] open device failed:%x\n", __FUNCTION__, __LINE__, videofd);continue;} else {uint32_t ishdmi;ret = ioctl(videofd, RKMODULE_GET_HDMI_MODE, (void*)&ishdmi);if (ret < 0) {printf("RKMODULE_GET_HDMI_MODE Failed\n");close(videofd);continue;}printf("%s RKMODULE_GET_HDMI_MODE:%d\n",kV4l2DevicePath,ishdmi);if (ishdmi) {mipifd = videofd;printf("MipiHdmi fd:%d\n",mipifd);if (mipifd < 0) {return -1;}}}}}   closedir(devdir);return ret;
}int main()
{int ret;int fd = -1;find_mipi_fd();fd = mipifd;if (fd < 0) {printf("find mipi dev fail\n");return -1;}//查询拔插状态struct v4l2_control control;control.id = V4L2_CID_DV_RX_POWER_PRESENT;ret = ioctl(fd, VIDIOC_G_CTRL, &control);if (ret < 0) {printf("Set POWER_PRESENT failed ,%d\n", ret);}if (control.value == 1) {//获取信号状态与分辨率int signal_status = 0;int ret = ioctl(fd, RK_HDMIRX_CMD_GET_SIGNAL_STABLE_STATUS, &signal_status);if (ret < 0)printf("RK_HDMIRX_CMD_GET_SIGNAL_STABLE_STATUS failed: %d\n", ret);printf("get signal status:%d\n", signal_status);struct v4l2_dv_timings timings;int err = ioctl(fd, VIDIOC_SUBDEV_QUERY_DV_TIMINGS, &timings);if (ret < 0)printf("VIDIOC_SUBDEV_QUERY_DV_TIMINGS failed: %d\n", ret);const struct v4l2_bt_timings *bt = &timings.bt;printf("hact:%d, hfp:%d, hs:%d, hbp:%d, vact:%d, vfp:%d, vs:%d, vbp:%d, interlace:%d\n",bt->width, bt->hfrontporch, bt->hsync, bt->hbackporch, bt->height, bt->vfrontporch, bt->vsync,bt->vbackporch, bt->interlaced);struct v4l2_subdev_format aFormat;err = ioctl(fd, VIDIOC_SUBDEV_G_FMT, &aFormat);if (err < 0)printf("VIDIOC_SUBDEV_G_FMT failed: %d\n", err);int fps;err = ioctl(fd, RK_HDMIRX_CMD_GET_FPS, &fps);if (err < 0)printf("RK_HDMIRX_CMD_GET_FPS failed: %d\n", err);printf("VIDIOC_SUBDEV_G_FMT: width: %d, height: %d, fps: %d\n", aFormat.format.width,aFormat.format.height, fps);int color_space = 0;ret = ioctl(fd, RK_HDMIRX_CMD_GET_COLOR_SPACE, &color_space);if (ret < 0)printf("RK_HDMIRX_CMD_GET_COLOR_SPACE failed: %d\n", ret);printf("get color space:%s\n", bus_color_space_str[color_space]);} else {printf("get 5V:%d, hdmi plug out\n", control.value);}close(fd);return 0;
}

http://www.dtcms.com/a/312049.html

相关文章:

  • Vulnhub ELECTRICAL靶机复现(附提权)
  • QPainter::CompositionMode解析
  • junit总@mockbaen与@mock的区别与联系
  • flutter分享到支付宝
  • Linux进程控制核心:创建·等待·终止·替换
  • Qt 信号和槽正常连接返回true,但发送信号后槽函数无响应问题【已解决】
  • 深入解析Java Stream Sink接口
  • Design Compiler:Milkyway库的创建与使用
  • 1-7〔 OSCP ◈ 研记 〕❘ 信息收集▸主动采集E:SMB基础
  • 硬件-可靠性学习DAY1——系统可靠性设计指南:从原理到实践
  • Markdown 中的图表 Mermaid 与 classDiagram
  • Thread 中的 run() 方法 和 start() 方法的
  • 笔记:C语言中指向指针的指针作用
  • MQTT协议测试环境部署
  • 错误: 找不到或无法加载主类 原因: java.lang.ClassNotFoundException
  • (nice!!!)(LeetCode 每日一题) 2561. 重排水果 (哈希表 + 贪心)
  • UNet改进(29):记忆增强注意力机制在UNet中的创新应用-原理、实现与性能提升
  • 【嵌入式汇编基础】-ARM架构基础(三)
  • 动态规划解最长回文子串:深入解析与优化问题
  • 【redis】基于工业界技术分享的内容总结
  • JS的作用域
  • 第15届蓝桥杯Python青少组中/高级组选拔赛(STEMA)2024年1月28日真题
  • sqli-labs:Less-20关卡详细解析
  • MFC 实现托盘图标菜单图标功能
  • 中州养老Day02:服务管理护理计划模块
  • 中之人模式下的虚拟主持人:动捕设备与面捕技术的协同驱动
  • 2025系规教材改革后,论文怎么写?
  • 错误处理_IncompatibleKeys
  • 在Linux上对固态硬盘进行分区、格式化和挂载的步骤
  • CH32V单片机启用 FPU 速度测试