在Jetson Orin Nan内核中添加IMX586摄像头驱动文件后,无法成功连接摄像头

我已经成功的将IMX586摄像头的驱动文件和设备树文件复制到了正确的位置,并且成功flash
大概步骤如下:
1.在tegra_defconfig文件中增加配置选项
2.将驱动文件复制到media/i2c路径下,并在makefile和kconfig中添加对应的信息
3.将dtsi文件复制到t23x/p3767/cvb下,并在顶层设备树文件中包含imx586设备树头文件

当我启动设备后,使用sudo dmesg |grep -i imx命令,可以看到内核执行了imx586的驱动文件:

nvidia-user@tegra-ubuntu:~/Desktop$ sudo dmesg |grep -i imx
[sudo] password for nvidia-user: 
[   11.708089] imx586 2-001a: imx586_probe : probing v4l2 sensor, i2c-2, 3 mode
[   11.708447] imx586 2-001a: tegracam sensor driver:imx586_v2.0.6
[   11.708451] imx586 2-001a: imx586_probe : tegracam_device_register end!!!--------
[   11.708454] imx586 2-001a: imx586_board_setup start !!!------------
[   11.711474] imx586 2-001a: imx586_board_setup camera_common_mclk_enable end !!!------------
[   11.711496] imx586_power_on: power_on
[   11.711498] imx586 2-001a: imx586_power_on: set reset gpio = 397.
[   11.711683] imx586 2-001a: imx586_board_setup imx586_power_on end !!!------------
[   11.711688] imx586 2-001a: imx586_probe : imx586_board_setup end!!!--------
[   11.711692] imx586 2-001a: imx586_probe : ctrlprops->gain_factor = 10, ctrlprops->framerate_factor = 1000000,ctrlprops->inherent_gain = 1!--------
[   11.711697] imx586 2-001a: imx586_probe : ctrlprops->min_gain_val = 10, ctrlprops->max_gain_val = 240,ctrlprops->min_hdr_ratio = 1, ctrlprops->max_hdr_ratio = 1 !--------
[   11.711703] imx586 2-001a: imx586_probe : ctrlprops->min_framerate = 1000000, ctrlprops->max_framerate = 30003939,ctrlprops->step_gain_val = 1, ctrlprops->step_framerate = 1 !--------
[   11.711708] imx586 2-001a: imx586_probe : ctrlprops->exposure_factor = 1000000, ctrlprops->default_gain = 10,ctrlprops->default_framerate = 30003939, ctrlprops->is_interlaced = 0, ctrlprops->interlace_type = 0 !--------
[   11.711714] imx586 2-001a: imx586_probe : ctrlprops->min_exp_time = 32 !--------
[   11.711718] imx586 2-001a: imx586_probe : ctrlprops->max_exp_time = 33333 !--------
[   11.711722] imx586 2-001a: imx586_probe : ctrlprops->step_exp_time = 2 !--------
[   11.711726] imx586 2-001a: imx586_probe : ctrlprops->default_exp_time = 33333 !--------
[   11.711730] imx586 2-001a: imx586_probe: frame_length:0, numctrls:0, mode_prop_idx:0, mode:0, csi_port:0, numlanes:4, numfmts: 7, def_mode: 0, def_width: 4000, def_height:3000, def_clk_freq:24000000, fmt_width: 4000, fmt_height:3000
[   11.711739] imx586 2-001a: imx586_probe: framerates:30, num_framerates:1, mode:0, hdr_en:1
[   11.712292] imx586 2-001a: imx586_write_reg: i2c write reg failed, addr: 0x0204, val: 00, err: -121
[   11.712300] imx586 2-001a: Error -121 in control hdl setup
[   11.712308] imx586 2-001a: Failed to init ctrls imx586
[   11.712311] imx586 2-001a: tegra camera subdev registration failed
[   11.722088] imx586: probe of 2-001a failed with error -121

不幸的是,出现了错误,出现问题的函数是:
imx586_probe() → tegracam_v4l2subdev_register() → tegracam_ctrl_handler_init()

根据我的判断,似乎是i2c的连接出现了问题,因为当我使用i2cdetect -l后,信息如下:

nvidia-user@tegra-ubuntu:~/Desktop$ sudo i2cdetect -l
i2c-3	i2c       	3190000.i2c                     	I2C adapter
i2c-1	i2c       	c240000.i2c                     	I2C adapter
i2c-8	i2c       	31e0000.i2c                     	I2C adapter
i2c-6	i2c       	31c0000.i2c                     	I2C adapter
i2c-4	i2c       	Tegra BPMP I2C adapter          	I2C adapter
i2c-2	i2c       	3180000.i2c                     	I2C adapter
i2c-0	i2c       	3160000.i2c                     	I2C adapter
i2c-9	i2c       	NVIDIA SOC i2c adapter 0        	I2C adapter
i2c-7	i2c       	c250000.i2c                     	I2C adapter
i2c-5	i2c       	31b0000.i2c                     	I2C adapter

在imx586的设备树节点中,使用的是3180000和31e0000

	i2c@3180000 {	
		imx586_a@34 {		
			// cam0_mclk
			clocks = <&bpmp_clks TEGRA234_CLK_EXTPERIPH1>,
					<&bpmp_clks TEGRA234_CLK_PLLP_OUT0>;

			clock-names = "extperiph1", "pllp_grtba";
			mclk = "extperiph1";
			clock-frequency = <24000000>;
			//status = "okay";

			reset-gpios = <&tegra_main_gpio CAM0_PWDN GPIO_ACTIVE_HIGH>;   //also for VCM_2V8 en
		};
	};
	
	i2c@31e0000 {
		imx586_c@34 {		
			// cam1_mclk
			clocks = <&bpmp_clks TEGRA234_CLK_EXTPERIPH2>,
					<&bpmp_clks TEGRA234_CLK_PLLP_OUT0>;
			clock-names = "extperiph2", "pllp_grtba";
			mclk = "extperiph2";
			clock-frequency = <24000000>;
			//status = "okay";

			reset-gpios = <&tegra_main_gpio CAM1_PWDN GPIO_ACTIVE_HIGH>;   //also for VCM_2V8 en
			
		};
	};

但是当我使用 sudo i2cdetect -y 2这个命令后,并没有检测到地址,并且在内核的日志信息中
告诉了我往imx586的0x0204进行地址写是失败的,所以我怀疑是i2c有问题
但是我不清楚具体问题出在哪里,是否是设备树文件不合适
如果有需要的话我可以上传我的设备树文件

hello 1602972632,

it’s shown i2c write reg failed with address 0x204, and it’s follow-by Error -121 in control hdl setup.
please examine what’s this function called, and please check all those settings has program correctly.

我查看了驱动文件,出现问题的函数是这个,但我不清楚返回的错误码代表什么含义

hello 1602972632,

it’s calling your sensor driver function to have sanity check before register camera device to linux kernel,
please dig into your sensor driver, to check which paragraph return the such failure.

anyways, according to the logs… Error -121 in control hdl setup, what’s hdl meant here? you may have a quick try to disable this function for testing.

你好,我更正一下我的问题:
static int imx586_write_reg(struct camera_common_data *s_data, u16 addr, u8 val)
{
int err;
struct device *dev = s_data->dev;

err = regmap_write(s_data->regmap, addr, val);

if (err){
	dev_err(dev, "%s: i2c write reg failed, addr: 0x%04x, val: %02x, err: %d\n",__func__, addr, val, err);
}
else dev_info(dev,"%s: i2c write reg sucess addr: 0x%04x, val: %02x, err: %d\n",__func__, addr, val, err);	

return err;

}
我有一个往imx586摄像头寄存器地址写入值的函数,在日志中,执行了该函数,往地址0x0204中写入值。
返回值是-121的错误码
我想知道,-121这个错误码代表什么错误?是地址不正确?还是i2c连接有问题,还是硬件本身的问题

hello 1602972632,

it’s error return by the sensor side. assume it’s standard syscall, you may refer to below for error reports.
for instance, $public_sources/kernel_src/kernel/kernel-5.10/include/uapi/asm-generic/errno.h

the failure is mapping to… #define EREMOTEIO 121 /* Remote I/O error */
it’s communication failure, you may review the i2c setting for register programming.

这个错误码是否代表我的硬件有问题,还是我的设备树有问题

hello 1602972632,

you may have a quick try by skipping register write (i.e. imx586_write_reg) to check whether it could register video node correctly.
if yes, there’s no issue on device tree side.

你的意思是,往摄像头的寄存器地址进行写操作imx586_write_reg 和 注册节点tegracam_v4l2subdev_register是相互独立的,注释掉写寄存器操作并不影响我注册节点的功能。
而影响注册节点tegracam_v4l2subdev_register的结果只会收到设备树dtsi的影响。
而返回值为121代表无法通信,与注册节点没有关系?

sensor probing will also have sanity check before register camera device to linux kernel, it won’t register video nodes if there’s failure.