madrat
Posts: 3
Joined: Sat Jul 31, 2021 1:17 pm

Two ADV7280M on One I2C bus

Sat Jul 31, 2021 1:57 pm

Hello, I have a problem with a custom CM4 board, which connects two ADV7280M (with address 0x20 and 0x21) on the same i2c bus (i2c0, GPIO 0 & 1).

Firstly, I follow the https://datasheets.raspberrypi.org/cmio ... ualcam.dts set pin defines.

Code: Select all

pin_define@NUM_CAMERAS {
               type = "internal";
               number = <2>;
            };
pin_define@CAMERA_0_I2C_PORT { type = "internal"; number = <0>; };
pin_define@CAMERA_0_SDA_PIN { type = "internal"; number = <0>; };
pin_define@CAMERA_0_SCL_PIN { type = "internal"; number = <1>; };
pin_define@CAMERA_1_I2C_PORT { type = "internal"; number = <0>; };
pin_define@CAMERA_1_SDA_PIN { type = "internal"; number = <0>; };
pin_define@CAMERA_1_SCL_PIN { type = "internal"; number = <1>; };
Modify the adv7282m-overlay.dts to use i2c0, and duplicate a csi0 version(original is csi1) named adv728x-m-csi0.

Code: Select all

// SPDX-License-Identifier: GPL-2.0-only
// Definitions for Analog Devices ADV7282-M video to CSI2 bridge on VC I2C bus
/dts-v1/;
/plugin/;

/{
	compatible = "brcm,bcm2835";

	fragment@0 {
		target = <&i2c0>;
		__overlay__ {
			#address-cells = <1>;
			#size-cells = <0>;
			status = "okay";

			adv728x: adv728x@21 {
				compatible = "adi,adv7282-m";
				reg = <0x21>;
				status = "okay";
				clock-frequency = <24000000>;
				port {
					adv728x_0: endpoint {
						remote-endpoint = <&csi0_ep>;
						clock-lanes = <0>;
						data-lanes = <1>;
						link-frequencies =
							/bits/ 64 <297000000>;

						mclk-frequency = <12000000>;
					};
				};
			};
		};
	};
	fragment@1 {
		target = <&csi0>;
		__overlay__ {
			status = "okay";

			port {
				csi0_ep: endpoint {
					remote-endpoint = <&adv728x_0>;
					data-lanes = <1>;
				};
			};
		};
	};
	fragment@2 {
		target = <&i2c0if>;
		__overlay__ {
			status = "okay";
		};
	};

	fragment@3 {
		target = <&i2c0mux>;
		__overlay__ {
			status = "okay";
		};
	};

	__overrides__ {
		addr =			<&adv728x>,"reg:0";
	};
};
And set this in config.txt

Code: Select all

dtoverlay=adv728x-m,addr=0x20,adv7280m=1
dtoverlay=adv728x-m-csi0,addr=0x21,adv7280m=1
Then, I get this from dmesg.

Code: Select all

[    5.532717] adv7180 0-0020: chip found @ 0x20 (bcm2835 (i2c@7e205000))
[    5.533083] i2c i2c-0: Failed to register i2c client dummy at 0x44 (-16)
[    5.533116] adv7180: probe of 0-0021 failed with error -16
Get this from i2cdetect -y 0

Code: Select all

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: UU 21 -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- UU -- UU -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- 68 -- -- 6b -- -- -- -- 
70: -- -- -- -- -- -- -- --  
But if I comment out any line of dtoverlay, the remain one works.

I try to combine two dts file in one with some modifications, nothing changes. This is my final dts file.

Code: Select all

// SPDX-License-Identifier: GPL-2.0-only
// Definitions for Analog Devices ADV7282-M video to CSI2 bridge on VC I2C bus
/dts-v1/;
/plugin/;

/{
	compatible = "brcm,bcm2835";

	fragment@0 {
		target = <&i2c0>;
		__overlay__ {
			#address-cells = <1>;
			#size-cells = <0>;
			status = "okay";

			adv728x_csi0: adv728x@21 {
				compatible = "adi,adv7280-m";
				reg = <0x21>;
				status = "okay";
				clock-frequency = <24000000>;
				port {
					adv728x_0: endpoint {
						remote-endpoint = <&csi0_ep>;
						clock-lanes = <0>;
						data-lanes = <1>;
						link-frequencies =
							/bits/ 64 <297000000>;

						mclk-frequency = <12000000>;
					};
				};
			};
		};
	};
	
	fragment@1 {
		target = <&csi0>;
		__overlay__ {
			status = "okay";

			port {
				csi0_ep: endpoint {
					remote-endpoint = <&adv728x_0>;
					data-lanes = <1>;
				};
			};
		};
	};
	fragment@2 {
		target = <&i2c0if>;
		__overlay__ {
			status = "okay";
		};
	};

	fragment@3 {
		target = <&i2c0mux>;
		__overlay__ {
			status = "okay";
		};
	};
	
	fragment@4 {
		target = <&i2c0>;
		__overlay__ {
			#address-cells = <1>;
			#size-cells = <0>;
			status = "okay";
			
			adv728x_csi1: adv728x@20 {
				compatible = "adi,adv7280-m";
				reg = <0x20>;
				status = "okay";
				clock-frequency = <24000000>;
				port {
					adv728x_1: endpoint {
						remote-endpoint = <&csi1_ep>;
						clock-lanes = <0>;
						data-lanes = <1>;
						link-frequencies =
							/bits/ 64 <297000000>;

						mclk-frequency = <12000000>;
					};
				};
			};
		};
	};
	
	fragment@5 {
		target = <&csi1>;
		__overlay__ {
			status = "okay";

			port {
				csi1_ep: endpoint {
					remote-endpoint = <&adv728x_1>;
					data-lanes = <1>;
				};
			};
		};
	};
};
How can I use both of the ADV7280M at the same time? Thank you very much!

6by9
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 11635
Joined: Wed Dec 04, 2013 11:27 am
Location: ZZ9 Plural Z Alpha, aka just outside Cambridge.

Re: Two ADV7280M on One I2C bus

Sat Jul 31, 2021 6:25 pm

Any use of dt-blob.bin is invalid when using the kernel drivers to control the hardware. They only apply when the firmware is trying to control an ov5647, imx219, or imx477 sensor.

You're problem is that ADV7280 and family use multiple I2C addresses, as documented in the "register maps" section of datasheet (page 23).
Main Map
The I2C slave address of the main map of the ADV7280/ ADV7280-M is set by the ALSB pin (see Table 15). The main
map allows the user to program the I2C slave addresses of the
VPP and CSI maps. The main map contains three sub maps: the
user sub map, the interrupt/VDP sub map, and User Sub Map 2.
These three sub maps are accessed by writing to the SUB_USR_EN
bits (Address 0x0E[6:5]) within the main map (see Figure 14 and Table 16).
...
VPP Map
The video postprocessor (VPP) map contains registers that
control the I2P core (interlaced-to-progressive converter). The VPP map has a programmable I2C slave address, which is
programmed using Register 0xFD in the user sub map of the
main map. The default value for the VPP map address is 0x00;
however, the VPP map cannot be accessed until the I2C slave
address is reset. The recommended I2C slave address for the
VPP map is 0x84. To reset the I2C slave address of the VPP map, write to the
VPP_SLAVE_ADDRESS[7:1] bits in the main register map
(Address 0xFD[7:1]). Set these bits to a value of 0x84 (I2C
write address; I2C read address is 0x85).

CSI Map (ADV7280-M Only)
The CSI map contains registers that control the MIPI CSI-2
output stream from the ADV7280-M. The CSI map has a programmable I2C slave address, which is
programmed using Register 0xFE in the user sub map of the
main map. The default value for the CSI map address is 0x00;
however, the CSI map cannot be accessed until the I2C slave
address is reset. The recommended I2C slave address for the
CSI map is 0x88.
The datasheet is quoting the full 8bit address byte, so the 0x84 referenced for VPP is address 0x42, and 0x88 for CSI is address 0x44. These are the additional addresses you see reported as UU from i2cdetect.

In order to load two instances you'll need to configure those secondary addresses rather than relying on the defaults.

The driver uses 2 defines to configure those addresses, and then programs them into the chip rather than relying on the defaults, but doesn't offer a way to configure them. I can't think of a clean way of doing it either.
You could do a slightly hacky approach of a switch/case or other conditional based on the main I2C address (adv7180_state->client->addr) for the alternate addresses. It's unlikely to be acceptable to mainline (or our kernel tree), but it would work.
Software Engineer at Raspberry Pi Trading. Views expressed are still personal views.
I'm not interested in doing contracts for bespoke functionality - please don't ask.

madrat
Posts: 3
Joined: Sat Jul 31, 2021 1:17 pm

Re: Two ADV7280M on One I2C bus

Sun Aug 01, 2021 2:26 am

Thank you 6by9. I learnt a lot!
I modified adv7180.c and set up two ADV7280Ms with different addresses, and both of them registered successfully in dmseg.

Code: Select all

[    5.496997] adv7180 0-0020: chip found @ 0x20 (bcm2835 (i2c@7e205000))
[    5.535924] adv7180 0-0021: chip found @ 0x21 (bcm2835 (i2c@7e205000))
And I can see 4 video devices from v4l2-ctl.

Code: Select all

pi@raspberrypi:~ $ v4l2-ctl --list-devices
bcm2835-codec-decode (platform:bcm2835-codec):
        /dev/video10
        /dev/video11
        /dev/video12

bcm2835-isp (platform:bcm2835-isp):
        /dev/video13
        /dev/video14
        /dev/video15
        /dev/video16

unicam (platform:fe800000.csi):
        /dev/video2
        /dev/video3

unicam (platform:fe801000.csi):
        /dev/video0
        /dev/video1
pi@raspberrypi:~ $ v4l2-ctl -D -d 0
Driver Info:
        Driver name      : unicam
        Card type        : unicam
        Bus info         : platform:fe801000.csi
        Driver version   : 5.10.52
        Capabilities     : 0x85a00001
                Video Capture
                Metadata Capture
                Read/Write
                Streaming
                Extended Pix Format
                Device Capabilities
        Device Caps      : 0x05200001
                Video Capture
                Read/Write
                Streaming
                Extended Pix Format
Media Driver Info:
        Driver name      : unicam
        Model            : unicam
        Serial           : 
        Bus info         : platform:fe801000.csi
        Media version    : 5.10.52
        Hardware revision: 0x00000000 (0)
        Driver version   : 5.10.52
Interface Info:
        ID               : 0x03000005
        Type             : V4L Video
Entity Info:
        ID               : 0x00000003 (3)
        Name             : unicam-image
        Function         : V4L2 I/O
        Flags         : default
        Pad 0x01000004   : 0: Sink
          Link 0x02000007: from remote pad 0x1000002 of entity 'adv7180 0-0020': Data, Enabled, Immutable
pi@raspberrypi:~ $ v4l2-ctl -D -d 1
Driver Info:
        Driver name      : unicam
        Card type        : unicam
        Bus info         : platform:fe801000.csi
        Driver version   : 5.10.52
        Capabilities     : 0x85a00001
                Video Capture
                Metadata Capture
                Read/Write
                Streaming
                Extended Pix Format
                Device Capabilities
        Device Caps      : 0x05a00000
                Metadata Capture
                Read/Write
                Streaming
                Extended Pix Format
Media Driver Info:
        Driver name      : unicam
        Model            : unicam
        Serial           : 
        Bus info         : platform:fe801000.csi
        Media version    : 5.10.52
        Hardware revision: 0x00000000 (0)
        Driver version   : 5.10.52
Interface Info:
        ID               : 0x0300000b
        Type             : V4L Video
Entity Info:
        ID               : 0x00000009 (9)
        Name             : unicam-embedded
        Function         : V4L2 I/O
        Pad 0x0100000a   : 0: Sink
pi@raspberrypi:~ $ v4l2-ctl -D -d 2
Driver Info:
        Driver name      : unicam
        Card type        : unicam
        Bus info         : platform:fe800000.csi
        Driver version   : 5.10.52
        Capabilities     : 0x85a00001
                Video Capture
                Metadata Capture
                Read/Write
                Streaming
                Extended Pix Format
                Device Capabilities
        Device Caps      : 0x05200001
                Video Capture
                Read/Write
                Streaming
                Extended Pix Format
Media Driver Info:
        Driver name      : unicam
        Model            : unicam
        Serial           : 
        Bus info         : platform:fe800000.csi
        Media version    : 5.10.52
        Hardware revision: 0x00000000 (0)
        Driver version   : 5.10.52
Interface Info:
        ID               : 0x03000005
        Type             : V4L Video
Entity Info:
        ID               : 0x00000003 (3)
        Name             : unicam-image
        Function         : V4L2 I/O
        Flags         : default
        Pad 0x01000004   : 0: Sink
          Link 0x02000007: from remote pad 0x1000002 of entity 'adv7180 0-0021': Data, Enabled, Immutable
pi@raspberrypi:~ $ v4l2-ctl -D -d 3
Driver Info:
        Driver name      : unicam
        Card type        : unicam
        Bus info         : platform:fe800000.csi
        Driver version   : 5.10.52
        Capabilities     : 0x85a00001
                Video Capture
                Metadata Capture
                Read/Write
                Streaming
                Extended Pix Format
                Device Capabilities
        Device Caps      : 0x05a00000
                Metadata Capture
                Read/Write
                Streaming
                Extended Pix Format
Media Driver Info:
        Driver name      : unicam
        Model            : unicam
        Serial           : 
        Bus info         : platform:fe800000.csi
        Media version    : 5.10.52
        Hardware revision: 0x00000000 (0)
        Driver version   : 5.10.52
Interface Info:
        ID               : 0x0300000b
        Type             : V4L Video
Entity Info:
        ID               : 0x00000009 (9)
        Name             : unicam-embedded
        Function         : V4L2 I/O
        Pad 0x0100000a   : 0: Sink
Only video0 and video2 are assigned to ADV7280M. What are video1 and video3 for? Thank you again.

6by9
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 11635
Joined: Wed Dec 04, 2013 11:27 am
Location: ZZ9 Plural Z Alpha, aka just outside Cambridge.

Re: Two ADV7280M on One I2C bus

Sun Aug 01, 2021 8:38 am

madrat wrote:
Sun Aug 01, 2021 2:26 am
Only video0 and video2 are assigned to ADV7280M. What are video1 and video3 for? Thank you again.
CSI2 supports multiple logical data streams over a single link, identified via a virtual channel field and a data type. This is typically used by image sensors to provide the sensor configuration alongside the frame that it produced so that AE etc know for definite the parameters used to generate the image.
The CSI2 receiver on the SoC supports saving two buffer streams - matching the image data configuration, and everything else. The first video node gets the image data, and the second everything else.
ADV7280 doesn't use any alternate data types, therefore /dev/video1 & 3 have no function with it. The CSI2 receiver driver should really not create the second node if the source subdev doesn't say it needs it - one for a bug fix at some point.
Software Engineer at Raspberry Pi Trading. Views expressed are still personal views.
I'm not interested in doing contracts for bespoke functionality - please don't ask.

Return to “Device Tree”