Enable I2C-Multiplexer (PCA9546) by using Overlay Device Tree (dtbo)

Hi!

I am working on a cape which - besides UARTs and other I2C-devices - makes use of a PCA9546 (from NXP) I2C-multiplexer (4 busses).

After trying to enable the mux by

echo pca9546 0x70 > /sys/class/i2c-adapter/i2c-1/new_device

I found out about the patch https://github.com/beagleboard/meta-beagleboard/blob/master/common-bsp/recipes-kernel/linux/linux-mainline-3.8/not-capebus/0111-i2c-DTify-pca954x-driver.patch

So I directed my attention towards the beloved (https://groups.google.com/forum/#!category-topic/beagleboard/beaglebone-capes/Iem_mHknIUM) device tree overlays.

After fiddling around for some time with the exact phrasing of the busses (somewhere it’s referred to as “pca9546-channel” instead of “-bus”, I got some success:

echo ibb-i2c > /sys/devices/bone_capemgr.8/slots

results in

[45340.486940] bone-capemgr bone_capemgr.8: part_number ‘ibb-i2c’, version ‘N/A’

[45340.497671] bone-capemgr bone_capemgr.8: slot #10: generic override

[45340.504492] bone-capemgr bone_capemgr.8: bone: Using override eeprom data at slot 10

[45340.512705] bone-capemgr bone_capemgr.8: slot #10: ‘Override Board Name,00A0,Override Manuf,ibb-i2c’

[45340.522936] bone-capemgr bone_capemgr.8: slot #10: Requesting part number/version based 'ibb-i2c-00A0.dtbo

[45340.533224] bone-capemgr bone_capemgr.8: slot #10: Requesting firmware ‘ibb-i2c-00A0.dtbo’ for board-name ‘Override Board Name’, version ‘00A0’

[45340.555078] bone-capemgr bone_capemgr.8: slot #10: dtbo ‘ibb-i2c-00A0.dtbo’ loaded; converting to live tree

[45340.567104] bone-capemgr bone_capemgr.8: slot #10: #1 overlays

[45340.602194] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc1

[45340.654809] pca954x 1-0070: registered 0 multiplexed busses for I2C mux pca9546

[45340.677634] bone-capemgr bone_capemgr.8: slot #10: Applied #1 overlays.

Unfortunately, registering 0 multiplexed busses is of no help…

the DTS:

/dts-v1/;

/plugin/;

/ {

compatible = “ti,beaglebone”, “ti,beaglebone-black”;

part-number = “ibb-i2c”;

version = “00A0”;

fragment@0 {

target = <&i2c2>;

overlay {

/* shut up DTC warnings */

#address-cells = <1>;

#size-cells = <0>;

/* DS1307 RTC module */

rtc@68 {

compatible = “dallas,ds3231”;

reg = <0x68>;

};

/* PCA9546 I2C multiplexer */

i2cmux@70 {

#address-cells = <1>;

#size-cells = <0>;

compatible = “nxp,pca9546”;

reg = <0x70>;

i2c@0 {

#address-cells = <1>;

#size-cells = <0>;

compatible = “nxp,pca954x-bus”;

reg = <0>;

};

i2c@1 {

#address-cells = <1>;

#size-cells = <0>;

compatible = “nxp,pca954x-bus”;

reg = <1>;

};

i2c@2 {

#address-cells = <1>;

#size-cells = <0>;

compatible = “nxp,pca954x-bus”;

reg = <2>;

};

i2c@3 {

#address-cells = <1>;

#size-cells = <0>;

compatible = “nxp,pca954x-bus”;

reg = <3>;

};

};

};

};

};

I tried adding some fake device to the i2c-busses as well, but no success. In reality, there are DS2483 Onewire-interfaces connected to these busses, for which there is no appropriate kernel driver (using owfs).

Any hints?

Best regards,
Robert

To answer my own question:

There is a “bug” in the patch mentioned above.

The PCA9546 is “incorrectly correctly” mapped to the struct entry of the PCA9546 (his own) - which is non-existent. The correct version, which is also used for the non-OH-version, maps the PCA9546 to the struct of the PCA9545. Replacing this everything works as expected.

BR
Robert

Just for clarification:

It says:

{ .compatible = "nxp,pca9546", PCA_TYPE_2_PTR(pca_9546), },

but it should say