How to detect sensors connected through i2c breakout board TCA9548A?

I have connected mpu6050 through TCA9548A and ran i2cdetect with only detects TCA9548A.
From what I have researched I need to modify the device-tree for my sensors connected through TCA9548A to get detected is that correct ?
If so can anyone provided some guidance or tutorial I can refer to?
Any help is appreciated, thanks.

The trick is to “just know” that TI TCA9548 and NXP PCA9548 use the same protocol. From that you learn just enough to be able to run git grep nxp,pca9548 to search the Linux kernel sources and that will take you the rest of the way.

The git grep command above should lead you to the devicetree bindings docs (Documentation/devicetree/bindings/i2c/i2c-mux.txt and Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt). It will also give you lots of examples of existing devicetrees with this part integrated that you can draw inspiration from!

I went through the steps you have given me and saw the example but now which dts file do I need to modify so i2cdetect shows sensors behind the mux.
Again, thanks you for the help

I’m a bit rusty since I haven’t done it in years but I think you’d be looking at editing:
https://git.linaro.org/landing-teams/working/qualcomm/kernel.git/tree/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi?h=debian-qcom-dragonboard410c-21.03#n161

And then following the " How to get and customize the kernel source code" section in the release notes.

After going through binding documentation
I think the mux bindings would be

mux@70 {
compatible = “nxp,pca9548”;
reg = <0x70>;
#address-cells = <1>;
#size-cells = <0>;

	i2c@7 {
		#address-cells = <1>;
		#size-cells = <0>;
		reg = <7>;

		gpio1: mpu6050@68 {
			compatible = "invensense,mpu6050";
			reg = <0x68>;
			interrupt-parent = <&gpio1>;
			interrupts = <18 1>;
			mount-matrix = "-0.984807753012208",  /* x0 */
						"0",                   /* y0 */
						"-0.173648177666930",  /* z0 */
						"0",                   /* x1 */
						"-1",                  /* y1 */
						"0",                   /* z1 */
						"-0.173648177666930",  /* x2 */
						"0",                   /* y2 */
						"0.984807753012208";   /* z2 */
		};
	};
	i2c@0 {
		#address-cells = <1>;
		#size-cells = <0>;
		reg = <0>;

		gpio2: ssd1309: oled@3c {
				compatible = "solomon,ssd1309fb-i2c";
				reg = <0x3c>;
				pwms = <&pwm 4 3000>;
				reset-gpios = <&gpio2 7>;
				reset-active-low;
				solomon,com-lrremap;
				solomon,com-invdir;
				solomon,com-offset = <32>;
		}; 
	};
};

But I am not sure where to put this in dtsi file ( kernel.git/tree/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi ) I think it should go in the soc section and then in i2c0

soc { i2c@78b6000 {
/* On Low speed expansion */
label = “LS-I2C0”;
status = “okay”;
};
};

But I was not able to find the proper syntax , also am I on the right path and doing this correctly?

For the new code (mux@70) I think you will simply have to experiment from here to ensure you have this fragment correct. I don’t expect anyone without actual hardware to be able to do more than read the examples you are already readying.

However, regarding where to add the new code, I put an explicit line number in the link to the .dtsi for a reason :wink: ! It points you exactly where I think it best to add the new DT code. Note also that, starting at line 172, there is an example of configuring an alternative I2C bus on the board (bridge@39). You should add mux@70 to blsp_i2c2 in a similar way (albeit with additional nesting to describe the sub-devices)

sorry for the late reply so I updated the dtsi file for just one sensor (mpu6050)

&blsp_i2c2 {
/* On Low speed expansion /
status = “okay”;
label = “LS-I2C0”;
tca9548@70 {
compatible = “nxp,pca9548”;
#address-cells = <1>;
#size-cells = <0>;
reg = <0x70>;
i2c@7 {
#address-cells = <1>;
#size-cells = <0>;
reg = <7>;
mpu6050@68 {
compatible = “invensense,mpu6050”;
reg = <0x68>;
interrupts = <18 1>;
mount-matrix = “-0.984807753012208”, /
x0 /
“0”, /
y0 /
“-0.173648177666930”, /
z0 /
“0”, /
x1 /
“-1”, /
y1 /
“0”, /
z1 /
“-0.173648177666930”, /
x2 /
“0”, /
y2 /
“0.984807753012208”; /
z2 */
};
};
};
};

running i2cdetect -r 0 gives

i2cdetect -r 0
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will probe file /dev/i2c-0 using receive byte commands.
I will probe address range 0x08-0x77.
Continue? [Y/n] y
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 – – – – – – –

any idea where I am going wrong?

To be honest I’m not sure you are doing anything wrong (other than not reading the i2cdetect manpage :wink: ).

UU means probing was skipped, because this address is currently in use by a driver. In other words the DT fragment you have added has caused the nxp,pca9548 driver to load correctly and grab the I2C address. It’s time to check the logs to see if the invensense,mpu6050 driver loaded and, if so, whether it is reachable!

Wouldn’t the tca9548 driver register a new bus? I.e. /dev/i2c-8 or something. You’d have to probe THAT bus to find the mpu6050 on 0x68.

FWIW: I’ve found that mpu6050’s (and related parts like mpu9x5x) are incredibly finnicky parts as far as i2c communications go. I’m pretty sure that most of the breakout boards with those chips are the result of dumpster diving behind the factory that makes them.