当前位置:   article > 正文

RK3588 camera驱动总结一_rk3588 imx416 驱动解读

rk3588 imx416 驱动解读

RK3588的硬件能力

ISP和VICAP的链接关系:

VICAP和ISP是独立的两个图像处理IP, VICAP所采集图像若要通过ISP处理,在驱动层面需要生成VICAP对应接口的v4l2 sub device链接到ISP对应的节点,以提供参数给ISP驱动使用。

1.RKISP 驱动

RKISP驱动主要是依据v4l2 / media framework实现硬件的配置、中断处理、控制 buffer轮转,以及控制subdevice(如 mipi dphy及sensor)的上下电等功能。

下面的框图描述了RKISP驱动的拓扑结构:

各节点描述如下:

csi subdev通过get_fmt获取sensor驱动多个pad格式的输出信息,对应csi的source pad。

2.RKVICAP 驱动
        RKVICAP驱动主要是基于v4l2 / media框架实现硬件的配置、中断处理、控制 buffer轮转,以及控制subdevice(如 mipi dphy及sensor)的上下电等功能。

        VICAP只有单核,同时拥有dvp/mipi两种接口,dvp接口对应一个rkvicap_dvp节点,mipi接口对应一个rkvicap_mipi_lvds节点,各节点可独立采集。

        为了将VICAP采集数据信息同步给isp驱动,需要将VICAP驱动生成的逻辑sditf节点链接到isp所生成的虚拟节点设备。DVP接口对应rkvicap_dvp_sditf节点,VICAP FULL的mipi/lvds接口对应rkvicap_mipi_lvds_sditf节点,VICAP LITE对应rkvicap_lite_sditf。

3.RK3588 VI结构

硬件支持最多采集7路sensor:6mipi + 1dvp,多sensor软件通路如下:

1. rk3588支持两个dcphy,节点名称分别为csi2_dcphy0/csi2_dcphy1。每个dcphy硬件支持RX/TX同时使用,对于camera输入使用的是RX。支持DPHY/CPHY协议复用;需要注意的是同一个dcphy的TX/RX只能同时使用DPHY或同时使用CPHY。其他dcphy参数请查阅rk3588数据手册。

2. rk3588支持2个dphy硬件,这里我们称之为dphy0_hw/dphy1_hw,两个dphy硬件都可以工作在fullmode 和split mode两种模式下。
        1. dphy0_hw
                1. full mode:节点名称使用csi2_dphy0,最多支持4 lane。
                2. split mode: 拆分成2个phy使用,分别为csi2_dphy1(使用0/1 lane)、csi2_dphy2(使用2/3 lane),每个phy最多支持2 lane。

                3. 当dphy0_hw使用full mode时,链路需要按照csi2_dphy1这条链路来配置,但是节点名称csi2_dphy1需要修改为csi2_dphy0,软件上是通过phy的序号来区分phy使用的模式。

        2. dphy1_hw

                1. full mode:节点名称使用csi2_dphy3,最多支持4 lane。

                2. split mode: 拆分成2个phy使用,分别为csi2_dphy4(使用0/1 lane)、csi2_dphy5(使用2/3 lane),每个phy最多支持2 lane。

                3. 当dphy1_hw使用full mode时,链路需要按照csi2_dphy4这条链路来配置,但是节点名称csi2_dphy4需要修改为csi2_dphy3,软件上是通过phy的序号来区分phy使用的模式。

3. 使用上述mipi phy节点,需要把对应的物理节点配置上。
(csi2_dcphy0_hw/csi2_dcphy1_hw/csi2_dphy0_hw/csi2_dphy1_hw)

4. 每个mipi phy都需要一个csi2模块来解析mipi协议,节点名称分别为mipi0_csi2~mipi5_csi2。

5. rk3588所有camera数据都需要通过vicap,再链接到isp。rk3588仅支持一个vicap硬件,这个vicap支持同时输入6路mipi phy,及一路dvp数据,所以我们将vicap分化成rkcif_mipi_lvds~rkcif_mipi_lvds5、rkcif_dvp等7个节点,各个节点的绑定关系需要严格按照框图的节点序号配置。

6. 每个vicap节点与isp的链接关系,通过对应虚拟出的XXX_sditf来指明链接关系。

7. rk3588支持2个isp硬件,每个isp设备可虚拟出多个虚拟节点,软件上通过回读的方式,依次从ddr读取每一路的图像数据进isp处理。对于多摄方案,建议将数据流平均分配到两个isp上。

8. 直通与回读模式:
        1. 直通:指数据经过vicap采集,直接发送给isp处理,不存储到ddr。需要注意的是hdr直通时,只有短帧是真正的直通,长帧需要存在ddr,isp再从ddr读取。
        2. 回读:指数据经过vicap采集到ddr,应用获取到数据后,将buffer地址推送给isp,isp再从ddr获取图像数据。

        3. 再dts配置时,一个isp硬件,如果只配置一个虚拟节点,默认使用直通模式,如果配置了多个虚拟节点默认使用回读模式。

4.CIS(cmos image sensor)驱动
imx464接dphy1为例:

  • data-lanes必须指明具体使用的lane数,否则无法识别为mipi 类型;
  • dphy需要链接到csi host节点,csi2_dphy3对应使用mipi4_csi2;
  • csi2_dphy3只是逻辑节点,需要依赖物理节点csi2_dphy1_hw。
  • rkcif_mipi_lvds4是vicap的其中一个逻辑节点,物理节点rkcif及对应iommu需要配置上。rkcif_mipi_lvds4_sditf是虚拟子节点,是rkcif_mipi_lvds4的虚拟节点,用来链接isp。
  • sensor驱动一般实现avdd/dvdd/dovdd三个电源操作,如果使用类似rk809分配出来的电源可以直接在sensor节点配置上,如果使用LDO等外部电源,使能脚是通过gpio控制,可以参考vcc_mipicsi1配置成电源节点,可以通过引用计数来上下电,适用于多设备使用同一电源。建议多摄时dvdd电源分开供应,avdd/dovdd可以共用,dvdd共用时,如果功率比较大,可能出现瞬时供应不足,电源有塌陷,影响到图像质量,甚至不出图。
  1. / {
  2. cam_ircut0: cam_ircut {
  3. status = "okay";
  4. compatible = "rockchip,ircut";
  5. ircut-open-gpios = <&gpio4 RK_PA6 GPIO_ACTIVE_HIGH>;
  6. ircut-close-gpios = <&gpio4 RK_PA7 GPIO_ACTIVE_HIGH>;
  7. rockchip,camera-module-index = <0>;
  8. rockchip,camera-module-facing = "back";
  9. };
  10. vcc_mipidphy0: vcc-mipidcphy0-regulator {
  11. compatible = "regulator-fixed";
  12. gpio = <&gpio1 RK_PB1 GPIO_ACTIVE_HIGH>;
  13. pinctrl-names = "default";
  14. pinctrl-0 = <&mipidphy0_pwr>;
  15. regulator-name = "vcc_mipidphy0";
  16. enable-active-high;
  17. };
  18. };
  19. &csi2_dphy0 {
  20. status = "okay";
  21. ports {
  22. #address-cells = <1>;
  23. #size-cells = <0>;
  24. port@0 {
  25. reg = <0>;
  26. #address-cells = <1>;
  27. #size-cells = <0>;
  28. mipidphy0_in_ucam0: endpoint@1 {
  29. reg = <1>;
  30. remote-endpoint = <&imx415_out0>;
  31. data-lanes = <1 2 3 4>;
  32. };
  33. };
  34. port@1 {
  35. reg = <1>;
  36. #address-cells = <1>;
  37. #size-cells = <0>;
  38. csidphy0_out: endpoint@0 {
  39. reg = <0>;
  40. remote-endpoint = <&mipi2_csi2_input>;
  41. };
  42. };
  43. };
  44. };
  45. &csi2_dphy0_hw {
  46. status = "okay";
  47. };
  48. &i2c3 {
  49. status = "okay";
  50. imx415: imx415@1a {
  51. compatible = "sony,imx415";
  52. reg = <0x1a>;
  53. clocks = <&cru CLK_MIPI_CAMARAOUT_M3>;
  54. clock-names = "xvclk";
  55. pinctrl-names = "default";
  56. pinctrl-0 = <&mipim0_camera3_clk>;
  57. power-domains = <&power RK3588_PD_VI>;
  58. pwdn-gpios = <&gpio1 RK_PB3 GPIO_ACTIVE_HIGH>;
  59. avdd-supply = <&vcc_mipidphy0>;
  60. rockchip,camera-module-index = <0>;
  61. rockchip,camera-module-facing = "back";
  62. rockchip,camera-module-name = "CMK-OT2022-PX1";
  63. rockchip,camera-module-lens-name = "IR0147-50IRC-8M-F20";
  64. lens-focus = <&cam_ircut0>;
  65. port {
  66. imx415_out0: endpoint {
  67. remote-endpoint = <&mipidphy0_in_ucam0>;
  68. data-lanes = <1 2 3 4>;
  69. };
  70. };
  71. };
  72. };
  73. &mipi2_csi2 {
  74. status = "okay";
  75. ports {
  76. #address-cells = <1>;
  77. #size-cells = <0>;
  78. port@0 {
  79. reg = <0>;
  80. #address-cells = <1>;
  81. #size-cells = <0>;
  82. mipi2_csi2_input: endpoint@1 {
  83. reg = <1>;
  84. remote-endpoint = <&csidphy0_out>;
  85. };
  86. };
  87. port@1 {
  88. reg = <1>;
  89. #address-cells = <1>;
  90. #size-cells = <0>;
  91. mipi2_csi2_output: endpoint@0 {
  92. reg = <0>;
  93. remote-endpoint = <&cif_mipi2_in0>;
  94. };
  95. };
  96. };
  97. };
  98. &pinctrl {
  99. cam {
  100. mipidphy0_pwr: mipidphy0-pwr {
  101. rockchip,pins =
  102. /* camera power en */
  103. <1 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>;
  104. };
  105. };
  106. };
  107. &rkcif {
  108. status = "okay";
  109. };
  110. &rkcif_mipi_lvds2 {
  111. status = "okay";
  112. port {
  113. cif_mipi2_in0: endpoint {
  114. remote-endpoint = <&mipi2_csi2_output>;
  115. };
  116. };
  117. };
  118. &rkcif_mipi_lvds2_sditf {
  119. status = "okay";
  120. port {
  121. mipi_lvds2_sditf: endpoint {
  122. remote-endpoint = <&isp0_vir0>;
  123. };
  124. };
  125. };
  126. &rkcif_mmu {
  127. status = "okay";
  128. };
  129. &rkisp0 {
  130. status = "okay";
  131. };
  132. &isp0_mmu {
  133. status = "okay";
  134. };
  135. &rkisp0_vir0 {
  136. status = "okay";
  137. port {
  138. #address-cells = <1>;
  139. #size-cells = <0>;
  140. isp0_vir0: endpoint@0 {
  141. reg = <0>;
  142. remote-endpoint = <&mipi_lvds2_sditf>;
  143. };
  144. };
  145. };

5.RK3588 camera驱动移植步骤

  1. 根据struct i2c_driver说明实现以下成员
    struct driver.name
    struct driver.pm
    struct driver. of_match_table
    probe函数
    remove函数
  2. probe函数实现细节描述: CIS 设备资源的获取,主要是解析DTS文件中定义资源,RK私有资源定义,命名方式如下rockchip,camera-module-xxx, 该部分资源会由驱动上传给用户态的camera_engine来决定IQ效果参数的匹配
  3. CIS设备资源定义,RK相关参考驱动一般包含以下几项:
  4. CIS设备ID号检查, 通过以上步骤获取必要资源后,建议驱动读取设备ID号以便检查硬件的准确性,当然该步骤非必要步骤.
  5. CIS v4l2设备以及media实体的初始化。v4l2子设备:v4l2_i2c_subdev_init,RK CIS驱动要求subdev拥有自己的设备节点供用户态rk_aiq访问,通过该设备节点实现曝光控制;media实体:media_entity_init

struct v4l2_subdev_ops说明实现v4l2子设备驱动,主要实现以下3个成员:

  • struct v4l2_subdev_core_ops
  • struct v4l2_subdev_video_ops
  • struct v4l2_subdev_pad_ops

struct v4l2_subdev_core_ops实现其回调函数,主要实现以下回调:

  • .s_power

s_power实现sensor的上下电操作,对于一些寄存器数组较长的sensor,可以归纳出公共部分的寄存器,在上电后执行,s_stream只配置不同分辨率配置必须的寄存器,加快切换速度。

  • .ioctl .compat_ioctl32

ioctl主要实现的RK私有控制命令
struct v4l2_subdev_video_ops主要实现以下回调函数:

struct v4l2_subdev_pad_ops主要实现以下回调函数:

struct v4l2_ctrl_ops主要实现以下回调

.s_ctrlRKISP driver、camera_engine通过设置不同的命令来实现CIS 曝光控制;

参考文档:

《Rockchip_Driver_Guide_VI_CN》

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/人工智能uu/article/detail/933273
推荐阅读
相关标签
  

闽ICP备14008679号