20251219给飞凌OK3588-C开发板适配Rockchip原厂的Buildroot【linux-6.1】系统时解决编译ov5645的驱动的时候出现probe挂载的问题

20251219给飞凌OK3588-C开发板适配Rockchip原厂的Buildroot【linux-6.1】系统时解决编译ov5645的驱动的时候出现probe挂载的问题
2025/12/19 14:15


缘起:给飞凌OK3588-C开发板适配Rockchip原厂的Buildroot【linux-6.1】后,需要使用ov5645的驱动框架来适配LVDS接口的105机芯。
按照以前的经验,首先关闭I2C的读写!
结果,肯定会出现某些地方遗漏的,只能通过编译器来检查问题了!


当你把荣品RD-RK3588开发板重新适配一把,就相当于从头做了一个项目:【荣品RD-RK3588开发板】。
当然,开发板的功能都是好的,你免除了调试的过程,也就没有解决相关硬件出错的经验/机会了!


1、出错的LOG:

[   55.223962] dwhdmi-rockchip fdea0000.hdmi: i2c read time out!
[   55.328042] dwhdmi-rockchip fdea0000.hdmi: i2c read time out!
[   55.328070] dwhdmi-rockchip fdea0000.hdmi: ddc read failed offset:0x1
[   55.431962] dwhdmi-rockchip fdea0000.hdmi: i2c read time out!
[   55.535963] dwhdmi-rockchip fdea0000.hdmi: i2c read time out!
[   55.639963] dwhdmi-rockchip fdea0000.hdmi: i2c read time out!
[   55.743960] dwhdmi-rockchip fdea0000.hdmi: i2c read time out!
[   55.847963] dwhdmi-rockchip fdea0000.hdmi: i2c read time out!
[   55.951963] dwhdmi-rockchip fdea0000.hdmi: i2c read time out!
[   56.055962] dwhdmi-rockchip fdea0000.hdmi: i2c read time out!
[   56.159961] dwhdmi-rockchip fdea0000.hdmi: i2c read time out!
[   56.263962] dwhdmi-rockchip fdea0000.hdmi: i2c read time out!
[   56.367963] dwhdmi-rockchip fdea0000.hdmi: i2c read time out!
[   56.367988] dwhdmi-rockchip fdea0000.hdmi: ddc read failed offset:0x1
[   56.471961] dwhdmi-rockchip fdea0000.hdmi: i2c read time out!
[   56.575961] dwhdmi-rockchip fdea0000.hdmi: i2c read time out!
[   56.679962] dwhdmi-rockchip fdea0000.hdmi: i2c read time out!
[   56.783961] dwhdmi-rockchip fdea0000.hdmi: i2c read time out!
[   56.887961] dwhdmi-rockchip fdea0000.hdmi: i2c read time out!
[   56.991962] dwhdmi-rockchip fdea0000.hdmi: i2c read time out!
[   57.095961] dwhdmi-rockchip fdea0000.hdmi: i2c read time out!
[   57.199962] dwhdmi-rockchip fdea0000.hdmi: i2c read time out!
[   57.303975] dwhdmi-rockchip fdea0000.hdmi: i2c read time out!
[   57.407962] dwhdmi-rockchip fdea0000.hdmi: i2c read time out!
[   57.407988] dwhdmi-rockchip fdea0000.hdmi: ddc read failed offset:0x1
[   57.408006] dwhdmi-rockchip fdea0000.hdmi: failed to get edid

root@rk3588-buildroot:/# 
root@rk3588-buildroot:/# 
root@rk3588-buildroot:/# 
root@rk3588-buildroot:/# 
root@rk3588-buildroot:/# 
root@rk3588-buildroot:/# v4l2-ctl --list-devices
[  253.519326] rkcif-mipi-lvds2: rkcif_update_sensor_info: stream[0] get remote terminal sensor failed!
[  253.519363] stream_cif_mipi_id0: update sensor info failed -19
[  253.519393] rkcif-mipi-lvds2: rkcif_update_sensor_info: stream[1] get remote terminal sensor failed!
rk_hdmirx (fdee0000.hdmirx-controller):
[  253.519404] stream_cif_mipi_id1: update sensor info failed -19
    /dev/video11
[  253.519428] rkcif-mipi-lvds2: rkcif_update_sensor_info: stream[2] get remote terminal sensor failed!

[  253.519438] stream_cif_mipi_id2: update sensor info failed -19
rkcif-mipi-lvds2 (platform:rkcif-mipi-lvds2):
[  253.519462] rkcif-mipi-lvds2: rkcif_update_sensor_info: stream[3] get remote terminal sensor failed!
    /dev/media0
[  253.519472] stream_cif_mipi_id3: update sensor info failed -19

[  253.519495] rkcif-mipi-lvds2: rkcif_update_sensor_info: stream[0] get remote terminal sensor failed!
JKY: JKY (usb-xhci-hcd.5.auto-1):
[  253.519505] rkcif_scale_ch0: update sensor info failed -19
    /dev/video12
[  253.519528] rkcif-mipi-lvds2: rkcif_update_sensor_info: stream[1] get remote terminal sensor failed!
    /dev/video13
[  253.519538] rkcif_scale_ch1: update sensor info failed -19
    /dev/media1
[  253.519562] rkcif-mipi-lvds2: rkcif_update_sensor_info: stream[2] get remote terminal sensor failed!

[  253.519571] rkcif_scale_ch2: update sensor info failed -19
Failed to open /dev/video0: No such device
[  253.519619] rkcif-mipi-lvds2: rkcif_update_sensor_info: stream[3] get remote terminal sensor failed!
root@rk3588-buildroot:/# [  253.519630] rkcif_scale_ch3: update sensor info failed -19
[  253.519657] rkcif-mipi-lvds2: rkcif_update_sensor_info: stream[0] get remote terminal sensor failed!
[  253.519667] rkcif_tools_id0: update sensor info failed -19
[  253.519691] rkcif-mipi-lvds2: rkcif_update_sensor_info: stream[1] get remote terminal sensor failed!
[  253.519700] rkcif_tools_id1: update sensor info failed -19
[  253.519982] rkcif-mipi-lvds2: rkcif_update_sensor_info: stream[2] get remote terminal sensor failed!
[  253.519995] rkcif_tools_id2: update sensor info failed -19
[  253.521186] rkcif-mipi-lvds2: rkcif_update_sensor_info: stream[0] get remote terminal sensor failed!
[  253.521202] stream_cif_mipi_id0: update sensor info failed -19

root@rk3588-buildroot:/# 
root@rk3588-buildroot:/# 
root@rk3588-buildroot:/# 
root@rk3588-buildroot:/# 
root@rk3588-buildroot:/# dmesg | grep ov56
[    2.901416] ov5645 1-003c: supply vdddo not found, using dummy regulator
[    2.901461] ov5645 1-003c: supply vdda not found, using dummy regulator
[    2.901480] ov5645 1-003c: supply vddd not found, using dummy regulator
[    2.901504] ov5645 1-003c: cannot get enable gpio
[    2.901564] ov5645: probe of 1-003c failed with error -2

root@rk3588-buildroot:/# 
root@rk3588-buildroot:/# 


2、【在probe中找不到reset/enable。也就是poweron异常直接退出了,摄像头ov5645/105机芯就不会被挂载并最终生成设备节点:/dev/video0】
Y:\new_disk_4t\wyb\A8\rk3588_linux6.1_release_v1.2.0_20241220\kernel-6.1\drivers\media\i2c\ov5645.c

static const struct v4l2_subdev_ops ov5645_subdev_ops = {
    .core = &ov5645_core_ops,
    .video = &ov5645_video_ops,
    .pad = &ov5645_subdev_pad_ops,
};

static int ov5645_probe(struct i2c_client *client)
{
    struct device *dev = &client->dev;
    struct device_node *endpoint;
    struct ov5645 *ov5645;
    u8 chip_id_high, chip_id_low;
    unsigned int i;
    u32 xclk_freq;
    char facing[2];
    int ret;

    ov5645 = devm_kzalloc(dev, sizeof(struct ov5645), GFP_KERNEL);
    if (!ov5645)
        return -ENOMEM;

    ov5645->i2c_client = client;
    ov5645->dev = dev;

    endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
    if (!endpoint) {
        dev_err(dev, "endpoint node not found\n");
        return -EINVAL;
    }

    ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint),
                     &ov5645->ep);

    of_node_put(endpoint);

    if (ret < 0) {
        dev_err(dev, "parsing endpoint node failed\n");
        return ret;
    }

    if (ov5645->ep.bus_type != V4L2_MBUS_CSI2_DPHY) {
        dev_err(dev, "invalid bus type, must be CSI2\n");
        return -EINVAL;
    }

    ret = of_property_read_u32(dev->of_node, RKMODULE_CAMERA_MODULE_INDEX,
                   &ov5645->module_index);
    if (ret) {
        dev_warn(dev, "could not get module index!\n");
        ov5645->module_index = 0;
    }

    ret |= of_property_read_string(dev->of_node, RKMODULE_CAMERA_MODULE_FACING,
                       &ov5645->module_facing);
    ret |= of_property_read_string(dev->of_node, RKMODULE_CAMERA_MODULE_NAME,
                       &ov5645->module_name);
    ret |= of_property_read_string(dev->of_node, RKMODULE_CAMERA_LENS_NAME,
                       &ov5645->len_name);
    if (ret) {
        dev_err(dev, "could not get module information!\n");
        return -EINVAL;
    }

    /* get system clock (xclk) */
    ov5645->xclk = devm_clk_get(dev, "xclk");
    if (IS_ERR(ov5645->xclk)) {
        dev_err(dev, "could not get xclk");
        return PTR_ERR(ov5645->xclk);
    }

    ret = of_property_read_u32(dev->of_node, "clock-frequency", &xclk_freq);
    if (ret) {
        dev_err(dev, "could not get xclk frequency\n");
        return ret;
    }

    /* external clock must be 24MHz, allow 1% tolerance */
    if (xclk_freq < 23760000 || xclk_freq > 24240000) {
        dev_err(dev, "external clock frequency %u is not supported\n",
            xclk_freq);
        return -EINVAL;
    }

    ret = clk_set_rate(ov5645->xclk, xclk_freq);
    if (ret) {
        dev_err(dev, "could not set xclk frequency\n");
        return ret;
    }

    for (i = 0; i < OV5645_NUM_SUPPLIES; i++)
        ov5645->supplies[i].supply = ov5645_supply_name[i];

    ret = devm_regulator_bulk_get(dev, OV5645_NUM_SUPPLIES,
                      ov5645->supplies);
    if (ret < 0)
        return ret;

    //ov5645->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_HIGH);
    //if (IS_ERR(ov5645->enable_gpio)) {
    //    dev_err(dev, "cannot get enable gpio\n");
    //    return PTR_ERR(ov5645->enable_gpio);
    //}
        //
    //ov5645->rst_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
    //if (IS_ERR(ov5645->rst_gpio)) {
    //    dev_err(dev, "cannot get reset gpio\n");
    //    return PTR_ERR(ov5645->rst_gpio);
    //}

    // 2024/7/26 19:28 gpio0B0 HDMI IN
    gpio_direction_output(8, 1);
    usleep_range(1000, 2000);
    
//LVDS12V_EN  GPIO4_B5 4*32+8+5=141
//FG_3V3_EN  GPIO3_B7  3*32+8+7=111
//FBGA_1V2_EN GPIO3_D0  3*32+8*3+0=120

    msleep(20);
    gpio_direction_output(120, 1);
    usleep_range(1000, 2000);
    
    gpio_direction_output(111, 1);
    usleep_range(1000, 2000);
    
    gpio_direction_output(84, 1);
    usleep_range(1000, 2000);
    
    //gpio_direction_output(120, 1);
    gpio_direction_output(141, 1);
    usleep_range(20000, 25000);

    ////printk("Firefly gpio putout finish \n");
    printk("---- wyb 2024/6/26 19:26 %s %s %d Firefly gpio putout finish\n", __FILE__, __FUNCTION__, __LINE__);


    mutex_init(&ov5645->power_lock);

    v4l2_ctrl_handler_init(&ov5645->ctrls, 9);
    v4l2_ctrl_new_std(&ov5645->ctrls, &ov5645_ctrl_ops,
              V4L2_CID_SATURATION, -4, 4, 1, 0);
    v4l2_ctrl_new_std(&ov5645->ctrls, &ov5645_ctrl_ops,
              V4L2_CID_HFLIP, 0, 1, 1, 0);
    v4l2_ctrl_new_std(&ov5645->ctrls, &ov5645_ctrl_ops,
              V4L2_CID_VFLIP, 0, 1, 1, 0);
    v4l2_ctrl_new_std(&ov5645->ctrls, &ov5645_ctrl_ops,
              V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
    v4l2_ctrl_new_std(&ov5645->ctrls, &ov5645_ctrl_ops,
              V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1);
    v4l2_ctrl_new_std_menu(&ov5645->ctrls, &ov5645_ctrl_ops,
                   V4L2_CID_EXPOSURE_AUTO, V4L2_EXPOSURE_MANUAL,
                   0, V4L2_EXPOSURE_AUTO);
    v4l2_ctrl_new_std_menu_items(&ov5645->ctrls, &ov5645_ctrl_ops,
                     V4L2_CID_TEST_PATTERN,
                     ARRAY_SIZE(ov5645_test_pattern_menu) - 1,
                     0, 0, ov5645_test_pattern_menu);
    ov5645->pixel_clock = v4l2_ctrl_new_std(&ov5645->ctrls,
                        &ov5645_ctrl_ops,
                        V4L2_CID_PIXEL_RATE,
                        1, INT_MAX, 1, 1);
    ov5645->link_freq = v4l2_ctrl_new_int_menu(&ov5645->ctrls,
                           &ov5645_ctrl_ops,
                           V4L2_CID_LINK_FREQ,
                           ARRAY_SIZE(link_freq) - 1,
                           0, link_freq);
    if (ov5645->link_freq)
        ov5645->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;

    ov5645->sd.ctrl_handler = &ov5645->ctrls;

    if (ov5645->ctrls.error) {
        dev_err(dev, "%s: control initialization error %d\n",
               __func__, ov5645->ctrls.error);
        ret = ov5645->ctrls.error;
        goto free_ctrl;
    }

    v4l2_i2c_subdev_init(&ov5645->sd, client, &ov5645_subdev_ops);
    ov5645->sd.internal_ops = &ov5645_internal_ops;
    ov5645->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
    ov5645->pad.flags = MEDIA_PAD_FL_SOURCE;
    ov5645->sd.dev = &client->dev;
    ov5645->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;

    ret = media_entity_pads_init(&ov5645->sd.entity, 1, &ov5645->pad);
    if (ret < 0) {
        dev_err(dev, "could not register media entity\n");
        goto free_ctrl;
    }

    ret = ov5645_s_power(&ov5645->sd, true);
    if (ret < 0) {
        dev_err(dev, "could not power up OV5645\n");
        goto free_entity;
    }

    //ret = ov5645_read_reg(ov5645, OV5645_CHIP_ID_HIGH, &chip_id_high);
    //if (ret < 0 || chip_id_high != OV5645_CHIP_ID_HIGH_BYTE) {
    //    dev_err(dev, "could not read ID high\n");
    //    ret = -ENODEV;
    //    goto power_down;
    //}
    //ret = ov5645_read_reg(ov5645, OV5645_CHIP_ID_LOW, &chip_id_low);
    //if (ret < 0 || chip_id_low != OV5645_CHIP_ID_LOW_BYTE) {
    //    dev_err(dev, "could not read ID low\n");
    //    ret = -ENODEV;
    //    goto power_down;
    //}
        //
    //dev_info(dev, "OV5645 detected at address 0x%02x\n", client->addr);
        //
    //ret = ov5645_read_reg(ov5645, OV5645_AEC_PK_MANUAL,
    //              &ov5645->aec_pk_manual);
    //if (ret < 0) {
    //    dev_err(dev, "could not read AEC/AGC mode\n");
    //    ret = -ENODEV;
    //    goto power_down;
    //}
        //
    //ret = ov5645_read_reg(ov5645, OV5645_TIMING_TC_REG20,
    //              &ov5645->timing_tc_reg20);
    //if (ret < 0) {
    //    dev_err(dev, "could not read vflip value\n");
    //    ret = -ENODEV;
    //    goto power_down;
    //}
        //
    //ret = ov5645_read_reg(ov5645, OV5645_TIMING_TC_REG21,
    //              &ov5645->timing_tc_reg21);
    //if (ret < 0) {
    //    dev_err(dev, "could not read hflip value\n");
    //    ret = -ENODEV;
    //    goto power_down;
    //}

    ov5645_s_power(&ov5645->sd, false);

    memset(facing, 0, sizeof(facing));
    if (strcmp(ov5645->module_facing, "back") == 0)
        facing[0] = 'b';
    else
        facing[0] = 'f';

    snprintf(ov5645->sd.name, sizeof(ov5645->sd.name), "m%02d_%s_%s %s",
         ov5645->module_index, facing,
         "ov5645", dev_name(ov5645->sd.dev));

    ret = v4l2_async_register_subdev_sensor(&ov5645->sd);
    if (ret) {
        dev_err(dev, "v4l2 async register subdev failed\n");
    }

    #if 0
    ret = v4l2_async_register_subdev(&ov5645->sd);
    if (ret < 0) {
        dev_err(dev, "could not register v4l2 device\n");
        goto free_entity;
    }
    #endif

    ov5645_entity_init_cfg(&ov5645->sd, NULL);

    return 0;

power_down:
    ov5645_s_power(&ov5645->sd, false);
free_entity:
    media_entity_cleanup(&ov5645->sd.entity);
free_ctrl:
    v4l2_ctrl_handler_free(&ov5645->ctrls);
    mutex_destroy(&ov5645->power_lock);

    return ret;
}

static void ov5645_remove(struct i2c_client *client)
{
    struct v4l2_subdev *sd = i2c_get_clientdata(client);
    struct ov5645 *ov5645 = to_ov5645(sd);

    v4l2_async_unregister_subdev(&ov5645->sd);
    media_entity_cleanup(&ov5645->sd.entity);
    v4l2_ctrl_handler_free(&ov5645->ctrls);
    mutex_destroy(&ov5645->power_lock);
}


3、挂载成功,但是还是有MIPI时钟的问题:

[   10.670636] RTL8211F Gigabit Ethernet stmmac-1:02: Downshift occurred from negotiated speed 1Gbps to actual speed 100Mbps, check cabling!
[   10.672349] rk_gmac-dwmac fe1c0000.ethernet eth0: Link is Up - 100Mbps/Full - flow control off
[   10.672395] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
[   13.135300] platform dp0-sound: deferred probe pending
[   13.135337] platform es8388-sound: deferred probe pending
[   13.135348] platform wireless-bluetooth: deferred probe pending
[   13.135358] platform mtd_vendor_storage: deferred probe pending
[   13.135369] platform sdio-pwrseq: deferred probe pending

root@rk3588-buildroot:/# 
root@rk3588-buildroot:/# 
root@rk3588-buildroot:/# dmesg | grep ov56
[    2.658907] ov5645 1-003c: supply vdddo not found, using dummy regulator
[    2.658954] ov5645 1-003c: supply vdda not found, using dummy regulator
[    2.658971] ov5645 1-003c: supply vddd not found, using dummy regulator
[    2.716347] ---- wyb 2024/6/26 19:26 drivers/media/i2c/ov5645.c ov5645_probe 1404 Firefly gpio putout finish
[    2.967355] ov5645 1-003c: Consider updating driver ov5645 to match on endpoints
[    2.967370] rockchip-csi2-dphy csi2-dphy0: dphy0 matches m00_b_ov5645 1-003c:bus type 5

root@rk3588-buildroot:/# 
root@rk3588-buildroot:/# 
root@rk3588-buildroot:/# 
root@rk3588-buildroot:/# [   33.357469] vcc3v3_lcd0_n: disabling

root@rk3588-buildroot:/# 

root@rk3588-buildroot:/# 
root@rk3588-buildroot:/# 
root@rk3588-buildroot:/# v4l2-ctl --list-devices
rk_hdmirx (fdee0000.hdmirx-controller):
    /dev/video11

rkcif (platform:rkcif-mipi-lvds2):
    /dev/video0

    /dev/video1
    /dev/video2
    /dev/video3
    /dev/video4
    /dev/video5
    /dev/video6
    /dev/video7
    /dev/video8
    /dev/video9
    /dev/video10
    /dev/media0

JKY: JKY (usb-xhci-hcd.5.auto-1):
    /dev/video12
    /dev/video13
    /dev/media1

root@rk3588-buildroot:/# 
root@rk3588-buildroot:/# 
, format=NV12, width=1920,height=1080 ! waylandsinkice=/dev/video0 ! video/x-raw,
Setting pipeline to PAUSED ...
Using mplane plugin for capture 
Pipeline is live and does not need PREROLL ...
Pipeline is PREROLLED ...
Setting pipeline to PLAYING ...
New clock: GstSystemClock
[  158.444960] rkcif-mipi-lvds2: stream[0] start streaming
[  158.446331] rkcif-mipi-lvds2: Allocate dummy buffer, size: 0x003f5000
[  158.446496] rockchip-mipi-csi2 mipi2-csi2: stream on, src_sd: 00000000fc79d983, sd_name:rockchip-csi2-dphy0
[  158.446517] rockchip-mipi-csi2 mipi2-csi2: stream ON
[  158.446557] rockchip-csi2-dphy0: dphy0, data_rate_mbps 1000
[  158.446594] rockchip-csi2-dphy csi2-dphy0: csi2_dphy_s_stream stream on:1, dphy1, ret 0
[  158.456770] mipi2-csi2-hw ERR1:0x10 (fs/fe mis,vc: 0) 
[  158.456781] rkcif-mipi-lvds2: ERROR: csi size err, intstat:0x1000001, size:0x0,0x0,0x0,0x0, cnt 1
[  158.456944] mipi2-csi2-hw ERR1:0x100 (f_seq,vc: 0) 
Redistribute latency...
Date: 2025-12-19 UTC
[08:15:43.728] seeing the first app
^Chandling interrupt.
Interrupt: Stopping pipeline ...
Execution ended after 0:00:11.037278967
[  169.476639] rkcif-mipi-lvds2: stream[0] start stopping, total mode 0x1, cur 0x1
Setting pipeline to NULL ...
[  169.476669] rkcif-mipi-lvds2: get vblank fail, vblank_def 0, vblank_curr 0
[  169.537010] rockchip-mipi-csi2 mipi2-csi2: stream off, src_sd: 00000000fc79d983, sd_name:rockchip-csi2-dphy0
[  169.537042] rockchip-mipi-csi2 mipi2-csi2: stream OFF
[  169.537065] rockchip-csi2-dphy csi2-dphy0: csi2_dphy_s_stream_stop stream stop, dphy1
[  169.537081] rockchip-csi2-dphy csi2-dphy0: csi2_dphy_s_stream stream on:0, dphy1, ret 0
[  169.537576] rkcif-mipi-lvds2: stream[0] stopping finished, dma_en 0x0
Freeing pipeline ...
root@rk3588-buildroot:/# 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值