【每周学习摘要01(25/01/23-25/01/29)】

Rk3566 OV2640调试记录

参考文献

camera调试:RK3588 MIPI/DVP camera关键配置
基于瑞芯微平台cif接口dvp相机的视频接入(ov2640、rv1126为例)
(BT656)rk3568制冷项目驱动开发流程汇总(只适用于部分模块CIF DVP等,自用)
瑞芯微摄像头移植流程和注意事项
(全志平台,仅供参考)MQ-r T113 ov2640驱动

订阅了个博客,可以当做文档?

https://blog.csdn.net/weixin_35723192/category_11824879_3.html

Rk3566 VI version 2.1 能力

其中注意瑞芯微rk3566/68平台的VICAP(rkcif)和ISP是两个不同的IP核,两个IP核都能进行capture.
其中rk3566的ISP21是lite版本,看描述是不支持HDR
rk3566/3568没有ispp这个东西,只有rv1126/rv1109/rk3588有(可能是因为VI 3.0才有这个)

详见ISP21/Rockchip_Driver_Guide_VI_CN_v1.1.3.pdf

GPIO/GRF/GRF_SYS

➜  ~ cd /sys/class/gpio
➜  gpio cd gpio144
➜  gpio144 echo 0 > value 
➜  gpio144 cd ../145
cd: no such file or directory: ../145
➜  gpio144 echo 0 > value
➜  gpio144 cd../g
➜  gpio144 cd ../gpio145
➜  gpio145 echo 0 > value
➜  gpio145 echo 1 > value
➜  gpio145 cd ../gpio144
➜  gpio144 echo 1 > value
➜  gpio144 devmem2 0xFDC60070 w 0x00FF0011
/dev/mem opened.
Memory mapped at address 0x7fb954d000.
Value at address 0xFDC60070 (0x7fb954d070): 0x0
Written 0xFF0011; readback 0x11

GRF 是 General Register File 的意思,其中有IOMUX的作用.
其中的SYS_GRF掌管了GPIO的IOMUX工作

我们可以通过devmem2 0xFDC60070 w 0x00FF0011来改变GPIO4_C bank 的复用,其中一个pin 4bit,高16位是用来做mask的.

GPIO 复用/linux pinctrl

比如dts长这样

device {
        pinctrl-names = "active", "idle";
        pinctrl-0 = <&state_0_node_a>;
        pinctrl-1 = <&state_1_node_a>, <&state_1_node_b>;
    };

然后active对应pinctrl-0.

#define OF_CAMERA_PINCTRL_STATE_DEFAULT "rockchip,camera_default"
gc4c33->pins_default = pinctrl_lookup_state(gc4c33->pinctrl, OF_CAMERA_PINCTRL_STATE_DEFAULT);
pinctrl_select_state(gc4c33->pinctrl, gc4c33->pins_default);

当然这里的names可以是任何名字, 然后每个组内可以有多个pins.
对于标有defaultpinstate, 驱动会默认进行pinctrl_select, 不需要在像i2c这种设备的源码里面手动再mux一遍. source:
The pin control core will automatically claim the default pinctrl state for us when the device is probed. If one defines an init state, the pinctrl core will automatically set pinctrl to this state before the probe() function, and then switch to the default state after probe() (unless the driver explicitly changed states already).

GPIO 复用查看

cat /sys/kernel/debug/pinctrl/pinctrl-rockchip-pinctrl/pinmux-pins

系统时钟树信息查看

➜  / cd /sys/kernel/debug/clk/clk_cif_out
➜  clk_cif_out cat clk_enable_count 
4

可以看到clock被开启了4次, 位于gc1054.c的测试代码:


// should enable 4 times
    ret = __gc1054_power_on(gc1054);
    ret = __gc1054_power_on(gc1054);
    ret = __gc1054_power_on(gc1054);
    ret = __gc1054_power_on(gc1054);

驱动c源码

需要在g_mbus_config中设置V4L2_MBUS_BT656, PARALLEL是给BT601用的

Linux 源码查看当前版本

找根目录Makefile前几行

25/01/23


可以看到pinmux 还没mux上去.可能mux工作是在rkcif_dvp驱动里面做的,但是i2c摄像头节点没有注册成功?(但是需要开起来).

[    8.849418] rkcif_dvp: get_remote_sensor: remote pad is null

看了下源码, pinmux在userspace不能通过sysfs改变, 只能查看. 然后根据迅为电子的教程看到改pinmux用到了这个函数:pinctrl_select_state, 于是查看了driver/media/i2c下面的调用, 发现改pinmux是在i2c driver里面做的,然后从linux4.19搬过来的gc1054驱动没有调用这个函数.

现在尝试把这个加进powerup函数里面

25/01/25

现在发现之前无法读取ov2640,第一个是因为CLK_CIF_OUT并非开启,然而IOMUX和clock确实都是开过的.后来用电压表量了一下,发现是clk在设备probe失败后自动关闭了,即使我在i2c设备内注释了所有关闭clock的函数.(可能是i2c驱动的上级驱动帮忙关闭的). 当我在开启clock后,关闭probe结束前加入一段很长的delay, 这样示波器能观察到稳定的波形。 delay 代码如下

    dev_info(&client->dev, "[debug] ov2640 xvclk start extreme long sleep(5s) - trial 1!");
    usleep_range(5 * 1000000, 6 * 1000000); // sleep 10s
    dev_info(&client->dev, "[debug] ov2640 xvclk stop extreme long sleep(5s) - trial 1!");
    i2c_smbus_write_byte_data(client, BANK_SEL, BANK_SEL_SENS);
    pid  = i2c_smbus_read_byte_data(client, PID);
    ver  = i2c_smbus_read_byte_data(client, VER);
    midh = i2c_smbus_read_byte_data(client, MIDH);
    midl = i2c_smbus_read_byte_data(client, MIDL);

然后发现OV2640的i2c地址(ID地址)是0x30. 然后现在dmesg信息如下, 看描述是因为ov2640这个驱动是主线的驱动(linux 5.10.160),并非能在rockchip那套平台(rkcif/rkisp)下面正常工作,因为rkcif(rkcif_dvp)会通过设备树里的endpoint链接,从而获取i2c v4l2subdev的信息,并且通过一些函数进行对应操作。
例如v4l2_subdev_video_ops里面缺乏.g_frame_interval, 然后v4l2_subdev_pad_ops里面缺乏.get_mbus_config,该函数是rkcif判断该摄像头是否为BT656/BT1120还是BT601,亦或是CSI2等类型,所以必须得有.可能在别的platform下面这个函数并非必须的.
还有一个很严重的误解, 才发现有外同步信号的叫BT.601/PARALLEL, 然后BT656没有外同步(HS,VS), 27MHz 的一般是BT656

[    5.273685] i2c /dev entries driver
[    5.276240] fan53555-regulator 0-001c: FAN53555 Option[12] Rev[15] Detected!
[    5.278280] vdd_cpu: supplied by vcc5v0_sys
[    5.288395] ov2640 2-0030: [debug] ov2640 xvclk start extreme long sleep(5s) - trial 1!
[   10.290330] ov2640 2-0030: [debug] ov2640 xvclk stop extreme long sleep(5s) - trial 1!
[   10.292579] ov2640 2-0030: ov2640 Product ID 26:42 Manufacturer ID 7f:a2
[   10.292613] ov2640 2-0030: [debug] ov2640 xvclk start extreme long sleep(5s) - trial 2!
[   15.320326] ov2640 2-0030: [debug] ov2640 xvclk stop extreme long sleep(5s) - trial 2!
[   15.320357] i2c i2c-2: OV2640 Probed
[   15.321788] rkcifhw fdfe0000.rkcif: Adding to iommu group 7
[   15.322363] rkcifhw fdfe0000.rkcif: can't request region for resource [mem 0xfdfe0000-0xfdfe7fff]
[   15.322494] rkcifhw fdfe0000.rkcif: No reserved memory region assign to CIF
[   15.322720] rkcif rkcif_dvp: rkcif driver version: v00.02.00
[   15.322880] rkcif rkcif_dvp: attach to cif hw node
[   15.322898] rkcif rkcif_dvp: rkcif wait line 0
[   15.322913] : terminal subdev does not exist
[   15.322925] : terminal subdev does not exist
[   15.322935] : terminal subdev does not exist
[   15.322946] : terminal subdev does not exist
[   15.324769] ov2640 2-0030: Async registered subdev
[   15.324792] rkcif_dvp: get mbus config failed for linking
[   15.324809] rkcif rkcif_dvp: Entity type for entity rkcif-dvp-sof was not initialized!
[   15.325155] rkcif_dvp: rkcif_update_sensor_info: get terminal ov2640 2-0030 g_frame_interval failed!
[   15.325182] rkcif_dvp: input mbus_code 0x2006, can't transform to RG10
[   15.325196] rkcif_dvp: input mbus_code 0x2006, can't transform to RG10
[   15.325208] rkcif_dvp: input mbus_code 0x2006, can't transform to RG10
[   15.325220] rkcif_dvp: input mbus_code 0x2006, can't transform to RG10
[   15.325241] rkcif_dvp: Async subdev notifier completed
[   15.325264] rkcif_dvp: rkcif_update_sensor_info: get terminal ov2640 2-0030 g_frame_interval failed!
[   15.325283] rkcif_dvp: There is not terminal subdev, not synchronized with ISP
[   15.325483] rkcif rkcif_dvp: No memory-region-thunderboot specified
[   15.327104] rockchip-mipi-csi2-hw fdfb0000.mipi-csi2-hw: enter mipi csi2 hw probe!
[   15.327343] rockchip-mipi-csi2-hw fdfb0000.mipi-csi2-hw: probe success, v4l2_dev:mipi-csi2-hw!
[   15.329032] rkisp_hw fdff0000.rkisp: Adding to iommu group 8
[   15.329287] rkisp_hw fdff0000.rkisp: is_thunderboot: 0
[   15.329330] rkisp_hw fdff0000.rkisp: can't request region for resource [mem 0xfdff0000-0xfdffffff]
[   15.329370] rkisp_hw fdff0000.rkisp: max input:0x0@0fps
[   15.329601] rkisp_hw fdff0000.rkisp: no find phandle sram
[   15.330220] rkisp rkisp-vir0: rkisp driver version: v02.03.00
[   15.330429] rkisp rkisp-vir0: No memory-region-thunderboot specified
[   15.330706] rkisp rkisp-vir0: Entity type for entity rkisp-isp-subdev was not initialized!
[   15.330738] rkisp rkisp-vir0: Entity type for entity rkisp-csi-subdev was not initialized!
[   15.334198] usbcore: registered new interface driver uvcvideo
[   15.334221] USB Video Class driver (1.1.1)
[   15.336410] Bluetooth: HCI UART driver ver 2.3
[   15.336436] Bluetooth: HCI UART protocol H4 registered
[   15.336447] Bluetooth: HCI UART protocol ATH3K registered

待做事项

现在可以直接参考gc2145的文档,因为这个是BT-601 YUV(外同步)来移植OV2640
也可以参考这个全志平台的移植MQ-r T113 ov2640驱动 因为都是MEDIA_BUS_FMT_UYUV8_2X8. 有些驱动是1X12,但我的硬件做的是2X8(8根CIF数据线). 所以只能看gc2145的代码和全志的这个(gc1054的驱动是MEDIA_BUS_FMT_SRGGB10_1X10, bayer RGB) 关于一个摄像头驱动用的哪种格式读取图像信息直接搜索关键词MEDIA_BUS_FMT. 然后RK的框架/硬件貌似不支持RGB565,见附录B MEDIA_BUS_FMT表,因为在整个文档都没搜到
这里说的RAW RGB 就是Bayer RAW RGB的意思.然后还有个RAW BW
主线的摄像头驱动貌似支持多种MEDIA_BUS_FMT, 详见ov2640/ov5640,不过一般在probe的时候都会选一个default类型.
基本上rk的摄像头只支持了一种特定的camera output数据格式,毕竟没必要写那么多别output format支持,主打一个能用就行.
gc2145用的是MEDIA_BUS_FMT_UYVY8_2X8,主线ov2640的default也是MEDIA_BUS_FMT_UYVY8_2X8
接下来的工作是照着这些资料完善主线ov2640的一些函数,基本上只要上报正确信息就好
注意gc2145 的vsync是low active,(见手册 7.1. Timing), 而ov2640的vsync是high active(待确认?,因为那个全志的人写的是high active但是我看手册确实是low active,可以看到gc1054也是vsync low active,凭逻辑判断也是这样,不放心多看几个V4L2_MBUS_PARALLEL的驱动,看了七八个都是这样的估计全志那个人写错了)但是hsync(href)都是high active,然后pclk_sample 基本上都是rising

设备树哪些必须要配置

关于ar0230为什么vs hs 都是高有效?

ar0230是一个桥接芯片并不是camera, 见手册第23页

当rkcif_dvp 成功链接后media拓扑长啥样?

这里的source(虽然是BT656的):rk3568制冷项目驱动开发流程汇总(只适用于部分模块CIF DVP等,自用)

第二个参考,虽然是rv1126的,但完整的展现了既有rkcif又有isp的情况下的拓扑(主要是知道哪个video设备是哪个产生的,哪个是裸的,哪个是经过处理的)
media-ctl 工具打印media control框架下media设备节点拓扑结构
第三个参考:

第四个参考:
(Rk的wiki,虽然是ISPv1)Rockchip-isp1

24/01/26

subdev-formats大全-kernel.org

Leave a Reply

Your email address will not be published. Required fields are marked *