I2c mux tca9548 for imx462

Hello,
I am struggling to enable driver for imx462 for my costume board, that is muxed after tca9548.

the camera works if I don’t “use” the mux. and make if pass the i2c signal by manually write the register of the mux.
Attached the dtsi of that the camera works, but not with the mux:
tegra194-camera-jakku-eimx462_working.dtsi (8.3 KB)

but when trying to add the tca9548, the mux works. but not the camera.
here is the dtsi:
tegra194-camera-jakku-eimx462_not_working.dtsi (8.6 KB)

I can see the i2c channels by

xx@xx-desktop:~$ i2cdetect -l
i2c-3	i2c       	3190000.i2c                     	I2C adapter
i2c-30	i2c       	i2c-8-mux (chan_id 0)           	I2C adapter
i2c-1	i2c       	c240000.i2c                     	I2C adapter
i2c-37	i2c       	i2c-8-mux (chan_id 7)           	I2C adapter
i2c-101	i2c       	15210000.display                	I2C adapter
i2c-8	i2c       	31e0000.i2c                     	I2C adapter
i2c-35	i2c       	i2c-8-mux (chan_id 5)           	I2C adapter
i2c-6	i2c       	31c0000.i2c                     	I2C adapter
i2c-33	i2c       	i2c-8-mux (chan_id 3)           	I2C adapter
i2c-4	i2c       	Tegra BPMP I2C adapter          	I2C adapter
i2c-31	i2c       	i2c-8-mux (chan_id 1)           	I2C adapter
i2c-2	i2c       	3180000.i2c                     	I2C adapter
i2c-0	i2c       	3160000.i2c                     	I2C adapter
i2c-36	i2c       	i2c-8-mux (chan_id 6)           	I2C adapter
i2c-7	i2c       	c250000.i2c                     	I2C adapter
i2c-34	i2c       	i2c-8-mux (chan_id 4)           	I2C adapter
i2c-5	i2c       	31b0000.i2c                     	I2C adapter
i2c-32	i2c       	i2c-8-mux (chan_id 2)           	I2C adapter
xx@xx-desktop:~$ i2cdetect -r -y 8
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: UU -- -- -- -- -- -- --                         
xx@xx-desktop:~$ i2cdetect -r -y 30
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- 22 -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- 42 -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: UU -- -- -- -- -- -- --

the diff is simple:

(kernel 5.0.2, Xavier NX)
What am I doing wrong?

not sure if its related or not. but I am using I2c bus 8, and not 3, as default. so I changed that too now:
from

#define CAMERA_I2C_MUX_BUS(x) (0x1e + x)

to
#define CAMERA_I2C_8_MUX_BUS(x) (80 + x)

still not working…

you may see-also Topic 192486 for more details of i2c bus multiplexer.

Thanks @JerryChang
I been looking at that post when trying to solve the issue. and couldn’t find my answer there.
the only thing that I am not sure about is the i2c-parent, but I think its relevant for i2c-mux-gpio only.

Can you explain how this part of the tree works:

	tegra-camera-platform {
		compatible = "nvidia, tegra-camera-platform";
		num_csi_lanes = <8>;
		max_lane_speed = <1500000>;
		min_bits_per_pixel = <10>;
		vi_peak_byte_per_pixel = <2>;
		vi_bw_margin_pct = <25>;
		max_pixel_rate = <160000>;
		isp_peak_byte_per_pixel = <5>;
		isp_bw_margin_pct = <25>;
        status = "okay";
		modules {
			cam_module0: module0 {
				badge = "prog_front_eimx462";
				position = "front";
				status = "okay";
				orientation = "1";
				cam_module0_drivernode0: drivernode0 {
					pcl_id = "v4l2_sensor";
					devname = "eimx462 80-0042";
					status = "okay";
					proc-device-tree = "/proc/device-tree/i2c@31e0000/tca9548@70/i2c@0/eimx462_a@42";
					
				};
			};
		};
	};

how I can assure that devname is correct? and proc-device-tree?

also, when the system boot and search the tree, how it does the search and find the compatible = "nvidia,eimx462"? it possible that the search doesn’t goes deep enough? or stops of some reason on one of the labels (i2c@31e0000 / tca9548_70: tca9548@70 / i2c@0)?

hello matanh,

i2c-parent meant which i2c address it’s actually used.
you may also check below for reference,
$public_sources/kernel_src/hardware/nvidia/soc/t19x/kernel-dts/tegra194-soc/tegra194-soc-i2c.dtsi
cam_i2c: i2c@3180000{...}

for reference drivers, such as IMX219 dual-camera settings on Xavier NX,
they’re based-on i2c@3180000, and using cam_i2cmux for sharing i2c address.
for example,

        cam_i2cmux{
                i2c-parent = <&cam_i2c>;
                i2c@0 {..}   rbpcv2_imx219_a@10 {..}
                i2c@1 {..}   rbpcv2_imx219_c@10 {..}

hence,
proc-device-tree should define as same as the device nodes are registered.
it will be…
proc-device-tree = "/proc/device-tree/cam_i2cmux/i2c@0/rbpcv2_imx219_a@10";
proc-device-tree = "/proc/device-tree/cam_i2cmux/i2c@1/rbpcv2_imx219_c@10";

you may also looking for device tree for other reference driver that using tca9548. for example, dual IMX274 on AGX Xavier platforms,

furthermore,
compatible property is used as device identifier. the Linux kernel uses this keyword to bind the device driver to a specific device.
you should have your camera driver with the same string, compatible = "nvidia,eimx462",
it’s kernel driver looking for this string for process, you may also adding some debug prints for confirmation.

Thanks again. I have looked at the referace you pointed. And the dtsi i attached based in them. Can you look at the attached files to understand where the error hide?
it seems that cam_i2cmux used when its i2c-mux-gpio, not for tca9548. I took my example from
/hardware/nvidia/platform/t19x/common/kernel-dts/t19x-common-modules/tegra194-camera-e3333-a00.dtsi.
Note that I don’t use i2c@3180000 , but i2c@31e0000

hello matanh,

please move tca6424_22_a GPIO control definitions out of tca9548_70/ i2c@0scope.
for example, it should be…

i2c@31e0000 {
		tca6424_22_a: tca6424@22 {...}

		tca9548_70: tca9548@70 {
			i2c@0 {
				eimx462_a@42 {

the tca6424_22_a is part of the camera it self. not part of the board. so its after the tca9548_70.
as you can see in the i2cdetect -r -y 8 replay above, its not being detected if not opening the mux to its port number 0.

hello matanh,

is the sysnode created correctly? are you able to parse the properties within file system?

yes, the device tree loaded properly. I can see it on /proc/device-tree (is that what you meant by sysnode?)
on one point i thought it might be related to ‘tegra-camera-platform’ not even trying to load the camera.
maybe issue with naming here:?

devname = "eimx462 80-0042";
proc-device-tree = "/proc/device-tree/i2c@31e0000/tca9548@70/i2c@0/eimx462_a@42";

another thought was that compatible = "nvidia,eimx462" is ‘too deep’ in the device tree so that why its not trying to be loaded

hello matanh,

is the sensor probing process detect imx462 during boot-up?
may I know what’s your kernel init logs, please gather the logs for reference, i.e. $ dmesg > klog.txt

FYI,
as long as your sensor driver, (i.e. imx462.c) has the same compatible property, linux kernel uses this keyword to bind the device driver to a specific device.

Hi @JerryChang,
No its not being detected, nor even trying to probe.
Attached two dmesg files. one without the tca9548 mux running (but I had to open the mux in the previus reboot):
dmesg_imxworks.txt (61.5 KB)

this on has:

[ 6.313602] pca953x 8-0022: using AI

(this is the i2c IO EXPENDER (tca6424_22_a) ! not the mux)
and:

[ 8.100785] [IMX462]: (imx462) probing v4l2 sensor.

The other is with the tca9548, but now the imx462 doesn’t work.
dmesg_imx_not_works.txt (62.0 KB)

and this one has

[ 6.707710] pca954x 8-0070: pca954x_probe()

[    6.707710] pca954x 8-0070: pca954x_probe() 2 
[    6.708256] pca954x 8-0070: supply vcc-pullup not found, using dummy regulator
[    6.708709] pca954x 8-0070: pca954x_probe: forcing device bus number, start 30.
[    6.708982] pca954x 8-0070: device detect skipped.
[    6.709168] pca954x 8-0070: pca954x_init() as builtin
[    6.709335] pca954x 8-0070: pca954x_init(addr=112, data->last_chan=0)
[    6.710270] i2c i2c-8: Added multiplexed i2c bus 30
[    6.713287] i2c i2c-8: Added multiplexed i2c bus 31
[    6.718223] i2c i2c-8: Added multiplexed i2c bus 32
[    6.722947] i2c i2c-8: Added multiplexed i2c bus 33
[    6.727634] i2c i2c-8: Added multiplexed i2c bus 34
[    6.732829] i2c i2c-8: Added multiplexed i2c bus 35
[    6.737205] i2c i2c-8: Added multiplexed i2c bus 36
[    6.742316] i2c i2c-8: Added multiplexed i2c bus 37
[    6.747005] pca954x 8-0070: registered 8 multiplexed busses for I2C switch pca9548

I2C switch pca9548 has register, but the later device should be i2c bus 30.
hecne,
please revise below for testing.

The dmesg I sent was before changing to 80.
you can see in my second thread that I changed it from 0x1e (30) to 80.
it doesn’t work either way. when I start the bus in 30, and devname = "eimx462 30-0042";
or when I start at 80 and devname = "eimx462 80-0042";

hello matanh,

please add some debug prints to your sensor driver, is the sensor power_on/off being called?

this is camera, and there is debug on the probing. do you have other ideas where else I can add debugging?
[IMX462]: (imx462) probing v4l2 sensor.

I added printf to some more internal functions:
cam_power_on(), cam_power_off(), cam_power_put(), cam_power_get()
still no output

hello matanh,

there should be sensor operations called by probing process.
you may check reference drivers as an example,

static struct camera_common_sensor_ops imx185_common_ops = {
        .numfrmfmts = ARRAY_SIZE(imx185_frmfmt),
        .frmfmt_table = imx185_frmfmt,
        .power_on = imx185_power_on,
        .power_off = imx185_power_off,
        .write_reg = imx185_write_reg,
        .read_reg = imx185_read_reg,
        .parse_dt = imx185_parse_dt,
        .power_get = imx185_power_get,
        .power_put = imx185_power_put,
        .set_mode = imx185_set_mode,
        .start_streaming = imx185_start_streaming,
        .stop_streaming = imx185_stop_streaming,
};

Hello Jerry.
As told here:

I have added printf to this functions.
and there is no printing of any when the imx is inside the pca9548.

Do you know how the scanning of the device tree works? for example, does the tegra-camera-platform try to find only cameras that are on proc-device-tree.
Or if there other method that might be debugged to understand the process and when it fails?

hello matanh,

there’ll be error reported once registration has failed.

FYI,
there’s Jetson V4L2 Camera Framework to register sensor device as V4L2 sub-device.
and… it initialize an instance of camera device (i.e. tc_dev) and calling those common operations as point-out in comment #19.

is the video node, /dev/video* created?
please running below to examine media controller settings, $ sudo media-ctl -p -d /dev/media0