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?
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 radxa-overlays/arch/arm64/boot/dts/rockchip/overlays/radxa-zero3-rpi-camera-v1.3.dts at main · radxa-pkg/radxa-overlays · GitHub
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.
Thank you very much! I finally get the camera to work!
Modification:
overlay:
pwdn-gpios = <&gpio3 RK_PC6 GPIO_ACTIVE_HIGH>;
source code:
ov9281->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
if (IS_ERR(ov9281->reset_gpio))
dev_warn(dev, "Failed to get reset-gpios\n");
ov9281->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW);
if (IS_ERR(ov9281->pwdn_gpio))
dev_warn(dev, "Failed to get pwdn-gpios\n");
That’s great! Congratulations.
Can you share your code to our overlay repo so that other people can use it directly ?
