I would like to use an OV9281 camera on Zero 3w. However, the official OS image only supports RaspberryPi Cameras which work on OV5647/IMX219. I wonder if recompiling the kernel will get the driver for OV9281 and the overlay. If so, could anyone gives some steps to build the kernel and get the driver?
I tried bsp and found that I can modify the kernel build config with make config
, and I found the support for OV9281, but after the build, I did not find anything related to OV9281, and the config seemed to roll back to the original one without OV9281. May I ask how to config kernel with bsp?
Support for OV9281 camera
first, you need compile the kernel with bsp in order to pull the kernel source,
then, enter the kernel source .src/linux, open the ov9281’s config with menuconfig , then copy the ov9281’s config and dependence to rk356x kconfig.conf, then compile the kernel again, finally you’ll get a kernel with ov9281 driver.
for Overlay dts, you can refer to https://github.com/radxa-pkg/radxa-overlays/blob/main/arch/arm64/boot/dts/rockchip/overlays/radxa-zero3-rpi-camera-v1.3.dts
for the usage of bsp tool, you can refer to https://docs.radxa.com/en/zero/zero3/low-level-dev/kernel
Thank you very much, but after some attempts I still can not get the camera to work.
I compiled the kernel, and tried to write the overlay file.
At first I got message like
[ 15.813587] ov9281 2-0060: driver version: 00.01.05
[ 15.813685] ov9281 2-0060: no pinctrl
[ 15.813794] ov9281 2-0060: Looking up avdd-supply from device tree
[ 15.813952] ov9281 2-0060: Looking up dovdd-supply from device tree
[ 15.813999] ov9281 2-0060: Looking up dvdd-supply from device tree
[ 15.816488] ov9281 2-0060: Unexpected sensor id(000000), ret(-5)
And I checked the i2c information with sudo i2cdetect -y 2
and I do get something on address 0x60 0x70
.
After some modification of the overlay, I still got
[ 15.203320] ov9281 2-0060: driver version: 00.01.05
[ 15.203362] ov9281 2-0060: Failed to get reset-gpios
[ 15.203407] ov9281 2-0060: no pinctrl
[ 15.203516] ov9281 2-0060: Looking up avdd-supply from device tree
[ 15.203672] ov9281 2-0060: Looking up dovdd-supply from device tree
[ 15.203718] ov9281 2-0060: Looking up dvdd-supply from device tree
[ 15.206100] ov9281 2-0060: Unexpected sensor id(000000), ret(-5)
And I found that the sudo i2cdetect -y 2
can no longer find the chip. Maybe I have broken my camera and I just bought a new one, together with a raspberry pi to test and make sure if any camera is working.
Could you please give some suggestions on how to debug this problem?
My final overlay file:
/dts-v1/;
/plugin/;
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/pinctrl/rockchip.h>
/ {
metadata {
title = "ov9281 from 5647";
compatible = "radxa,zero3";
category = "camera";
exclusive = "csi2_dphy0";
description = "Enable ov9281 from 5647";
};
};
&{/} {
clk_cam_24m: external-camera-clock-24m {
status = "okay";
compatible = "fixed-clock";
clock-frequency = <24000000>;
clock-output-names = "clk_cam_24m";
#clock-cells = <0>;
};
ov9281_avdd: fixedregulator_ov9281@0 {
compatible = "regulator-fixed";
regulator-name = "ov9281_avdd";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
regulator-always-on;
regulator-boot-on;
};
ov9281_dovdd: fixedregulator_ov9281@1 {
compatible = "regulator-fixed";
regulator-name = "ov9281_dovdd";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
regulator-boot-on;
};
ov9281_dvdd: fixedregulator_ov9281@2 {
compatible = "regulator-fixed";
regulator-name = "ov9281_dvdd";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
regulator-always-on;
regulator-boot-on;
};
};
&i2c2 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&i2c2m1_xfer>;
#address-cells = <1>;
#size-cells = <0>;
camera_ov9281: camera-ov9281@60 {
status = "okay";
compatible = "ovti,ov9281";
reg = <0x60>;
clocks = <&clk_cam_24m>;
clock-names = "xvclk";
pwdn-gpios = <&gpio3 RK_PC6 GPIO_ACTIVE_LOW>;
rockchip,camera-module-index = <0>;
rockchip,camera-module-facing = "back";
rockchip,camera-module-name = "ov9281-camera";
rockchip,camera-module-lens-name = "default";
avdd-supply = <&ov9281_avdd>;
dovdd-supply = <&ov9281_dovdd>;
dvdd-supply = <&ov9281_dvdd>;
port {
ucam_out0: endpoint {
remote-endpoint = <&mipi_in_ucam0>;
data-lanes = <1 2>;
};
};
};
};
&csi2_dphy_hw {
status = "okay";
};
&csi2_dphy0 {
status = "okay";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
mipi_in_ucam0: endpoint@1 {
reg = <1>;
remote-endpoint = <&ucam_out0>;
data-lanes = <1 2>;
};
};
port@1 {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
dphy0_out: endpoint@1 {
reg = <1>;
remote-endpoint = <&isp0_in>;
};
};
};
};
&rkisp_vir0 {
status = "okay";
port {
#address-cells = <1>;
#size-cells = <0>;
isp0_in: endpoint@0 {
reg = <0>;
remote-endpoint = <&dphy0_out>;
};
};
};
&rkisp {
status = "okay";
};
&rkisp_mmu {
status = "okay";
};
&rkcif_mmu {
status = "okay";
};
&rkcif {
status = "okay";
};
By the way, I tested with OV5647 cameras and they work fine. So the problem should be the driver/overlay/OV9281camera
The i2c address may need to be shifted one position to the right, please try this:
reg = <0x30>;
The OV9281 responds to two SCCB ID set by register SC_SCCB_ID1 (default 0xC0) and SC_SCCB_ID2 (default 0xE0).
One of them can be used as a broadcasting ID and the other one can be programmed to a unique ID.
Did you try the other register 0xE0 ? Then right shit one is 0x70.
I tried <0x60> and <0x70>, it seems to be no difference.
I also tried to hack the driver source code, as I found the error message is coming from
ret = ov9281_read_reg(client, OV9281_REG_CHIP_ID,
OV9281_REG_VALUE_16BIT, &id);
if (id != CHIP_ID) {
dev_err(dev, "Unexpected sensor id(%06x), ret(%d)\n", id, ret);
return -ENODEV;
}
the ret
is always -5
, even if I do not connect any camera physically. I assume that these code might not work well so I deleted them.
Now I can get the following information
radxa@radxa-zero3 ~> sudo dmesg | grep ov9
[ 12.361208] ov9281_dvdd: 1200 mV, enabled
[ 12.361521] reg-fixed-voltage fixedregulator_ov9281@2: ov9281_dvdd supplying 1200000uV
[ 12.361731] ov9281_dovdd: 1800 mV, enabled
[ 12.362035] reg-fixed-voltage fixedregulator_ov9281@1: ov9281_dovdd supplying 1800000uV
[ 12.362249] ov9281_avdd: 2800 mV, enabled
[ 12.362504] reg-fixed-voltage fixedregulator_ov9281@0: ov9281_avdd supplying 2800000uV
[ 14.572165] ov9281 2-0060: driver version: 00.01.05
[ 14.572230] ov9281 2-0060: Failed to get reset-gpios
[ 14.572282] ov9281 2-0060: no pinctrl
[ 14.572388] ov9281 2-0060: Looking up avdd-supply from device tree
[ 14.572588] ov9281 2-0060: Looking up dovdd-supply from device tree
[ 14.572707] ov9281 2-0060: Looking up dvdd-supply from device tree
[ 14.575372] ov9281 2-0060: Detected OV009281 sensor
[ 14.575433] rockchip-csi2-dphy csi2-dphy0: dphy0 matches m00_b_ov9281 2-0060:bus type 5
How ever when I tried to capture someting I got error
radxa@radxa-zero3 ~/pyopencv [1]> gst-launch-1.0 v4l2src device=/dev/video0 io-mode=4 ! videoconvert ! video/x-raw,format=NV12,width=1280,height=800 ! jpegenc ! multifilesink location=/home/radxa/test.jpg
Setting pipeline to PAUSED ...
Pipeline is live and does not need PREROLL ...
Pipeline is PREROLLED ...
Setting pipeline to PLAYING ...
New clock: GstSystemClock
ERROR: from element /GstPipeline:pipeline0/GstV4l2Src:v4l2src0: Failed to allocate required memory.
Additional debug info:
../sys/v4l2/gstv4l2src.c(700): gst_v4l2src_decide_allocation (): /GstPipeline:pipeline0/GstV4l2Src:v4l2src0:
Buffer pool activation failed
Execution ended after 0:00:00.017532707
ERROR: from element /GstPipeline:pipeline0/GstV4l2Src:v4l2src0: Internal data stream error.
Setting pipeline to NULL ...
Additional debug info:
../libs/gst/base/gstbasesrc.c(3127): gst_base_src_loop (): /GstPipeline:pipeline0/GstV4l2Src:v4l2src0:
streaming stopped, reason not-negotiated (-4)
Freeing pipeline ...
I guess there must be something wrong with the i2c
I added some printing debug and found that
[ 55.275992] ov9281 debug: enter __ov9281_start_stream
[ 55.276191] ov9281 debug: ret of ov9281_write_array: -5
[ 55.276198] m00_b_ov9281 2-0060: start stream failed while write regs
[ 140.761336] ov9281 debug: enter __ov9281_start_stream
[ 140.761561] ov9281 debug: ret of ov9281_write_array: -5
[ 140.761568] m00_b_ov9281 2-0060: start stream failed while write regs
where -5
should come from the error code #define EIO 5 /* I/O error */
any idea?
Add the reset-gpios attribute under the ov9281 node and let’s see the error later.