Adco
Posts: 42
Joined: Fri Mar 11, 2016 3:01 pm

Re: I2C mulitplexer support

Wed Apr 27, 2016 6:48 am

I managed to connect my Rpi to a PIC device using a P82B96 buffer chip over a fair distance. Works like a dream. This opens up huge potential for me to develope remote controller boards. I must just work out what would be nice to have points on a board. Things like relays, potentiometers, LEDs, isolated inputs, buzzers etc.

What would you like on a remote board?

Massi
Posts: 1691
Joined: Fri May 02, 2014 1:52 pm
Location: Italy

Re: I2C mulitplexer support

Wed Apr 27, 2016 7:28 am

Adco wrote:I managed to connect my Rpi to a PIC device using a P82B96 buffer chip over a fair distance. Works like a dream. This opens up huge potential for me to develope remote controller boards. I must just work out what would be nice to have points on a board. Things like relays, potentiometers, LEDs, isolated inputs, buzzers etc.

What would you like on a remote board?
i think you are quite OT in this topic, since the P82B96 is far from a multiplexer/switch (it's indeed fully transparent to the raspi)
Open a new topic

Adco
Posts: 42
Joined: Fri Mar 11, 2016 3:01 pm

Re: I2C mulitplexer support

Wed Apr 27, 2016 8:03 am

You are correct. OT. However, I had a minor discussion on page 2 about this and I thought I would give feedback. Hopefully someone will stumble across it and help them somehow. I know that I have found a lot of help readin OT comments. :)

Massi
Posts: 1691
Joined: Fri May 02, 2014 1:52 pm
Location: Italy

Re: I2C mulitplexer support

Wed Apr 27, 2016 8:25 am

yes, the discussion was with me :)
i'll probably participate in the new topic, but i think this one deserves IT comments since it's a very interesting feature the multiplexer support :)

Massi
Posts: 1691
Joined: Fri May 02, 2014 1:52 pm
Location: Italy

Re: I2C mulitplexer support

Wed Apr 27, 2016 8:36 am

it would be nice to implement the driver to use the "full" capabilities of the chip.

I mean, the multiplexer (let's say, the chip used by adafruit) can be used to select 8 single channels, but it can also be used to enable multiple channels at the same time.
This would be VERY useful to mix 3,3V and 5V devices in the same bus
Afaik, with the current driver it is not possible to do that
am i wrong?

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

Re: I2C mulitplexer support

Wed Apr 27, 2016 10:42 am

Massi wrote:it would be nice to implement the driver to use the "full" capabilities of the chip.

I mean, the multiplexer (let's say, the chip used by adafruit) can be used to select 8 single channels, but it can also be used to enable multiple channels at the same time.
This would be VERY useful to mix 3,3V and 5V devices in the same bus
Afaik, with the current driver it is not possible to do that
am i wrong?
Potentially useful, but not covered by the kernel i2c-mux framework as that is purely for muxes.

If you read the source for the pca954x driver, you'll see there's an enum for differentiating switches and muxes in this family of chips. pca954x_select_chan then changes behaviour dependent on type.
The linux-i2c mailing list would be the place for conversations over switch support instead of muxes, but be prepared for lots of discussion (and patches) for I2C devices that you're not at all interested in. I think the main question is how you'd present it to a client - muxes are easy as they're just extra devices, but how would you describe a set of busses?

TBH My view would be that one of these chips is excessive for just providing a mix and match bus voltage when a simple FET arrangement such as https://www.adafruit.com/products/757 will do that for you with less complexity.
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.

Massi
Posts: 1691
Joined: Fri May 02, 2014 1:52 pm
Location: Italy

Re: I2C mulitplexer support

Wed Apr 27, 2016 10:53 am

6by9 wrote:TBH My view would be that one of these chips is excessive for just providing a mix and match bus voltage when a simple FET arrangement such as https://www.adafruit.com/products/757 will do that for you with less complexity.
sure, my idea was just a practical appliance of what the chip can do :)
In my idea, the "core" is to be able to set the buses as multiple channel, so having control of what is written to the device by the driver
i.e., i could have only 7 muxed channels, where one is indeed a couple of channels

To enable channels, you should write to device something like
0b00000001
0b00000010
0b00000100
0b00001000
0b00010000
0b00100000
0b01000000
0b10000000

but you could also manage 7 "channels" writing like these
0b00000001
0b00000010
0b00000100
0b00001000
0b00010000
0b00100000
0b11000000

i'm too noob for this, i should look to the driver to understand what this part does and how it's translated to a i2c call :)

Code: Select all

reg = <0>;
ps: i don't really need this, that's just for talking :)

bludin
Posts: 5
Joined: Thu May 12, 2016 9:34 pm

Re: I2C mulitplexer support

Thu May 26, 2016 7:22 am

Is there any news on this subject? I've tried to reproduce some of the things here, but all the github links are dead...

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

Re: I2C mulitplexer support

Thu May 26, 2016 7:56 am

bludin wrote:Is there any news on this subject? I've tried to reproduce some of the things here, but all the github links are dead...
Everything is merged into the main Pi kernel - none of the interim files are needed.
First post updated to reflect that, particularly as things have changed to have the generic i2c-mux overlay rather than the 9548 specific one.
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.

Conner Labs
Posts: 45
Joined: Fri Jan 11, 2013 2:45 pm
Location: Glasgow
Contact: Website

Re: I2C mulitplexer support

Fri Mar 22, 2019 5:19 pm

Hi

I'm having some trouble reproducing this. Running Raspbian Jessie
Linux piggy 4.9.28-v7+ #998 SMP Mon May 15 16:55:39 BST 2017 armv7l GNU/Linux

The new generic i2c-mux overlay works fine when I test it with a single PCA9548. But this doesn't suit my use case: I want to use two PCA9548s at addresses 0x70, 0x71, as well as other I2C devices on the parent bus. (I guess that the addresses of devices on the parent bus aren't available for any devices on the child buses, irrespective of the setting of i2c-mux-idle-disconnect?)

So I tried making my own overlays. It seems to work OK except that I tried assigning I2C device numbers per 6by9's example and it had no effect. My intention is that the overlay for the first PCA9548 should instantiate i2c-10 to 17 and the second one i2c-20 to 27. But the first one appears as i2c-4 onwards regardless.

my overlay:

Code: Select all

// Umbrella I2C Mux overlay
// Modified to allow use of multiple muxes.
// Idle disconnect is used

/dts-v1/;
/plugin/;

/{
	compatible = "brcm,bcm2708";
	fragment@0 {
		target = <&i2c_arm>;
		__overlay__ {
			#address-cells = <1>;
			#size-cells = <0>;
			status = "okay";

			pca9548: mux@70 {
				compatible = "nxp,pca9548";
				reg = <0x70>;
				#address-cells = <1>;
				#size-cells = <0>;
        i2c-mux-idle-disconnect;

				i2cm0: i2c@0 {
					#address-cells = <1>;
					#size-cells = <0>;
					reg = <0>;
				};
				i2cm1: i2c@1 {
					#address-cells = <1>;
					#size-cells = <0>;
					reg = <1>;
				};
				i2cm2: i2c@2 {
					#address-cells = <1>;
					#size-cells = <0>;
					reg = <2>;
				};
				i2cm3: i2c@3 {
					#address-cells = <1>;
					#size-cells = <0>;
					reg = <3>;
				};
				i2cm4: i2c@4 {
					#address-cells = <1>;
					#size-cells = <0>;
					reg = <4>;
				};
				i2cm5: i2c@5 {
					#address-cells = <1>;
					#size-cells = <0>;
					reg = <5>;
				};
				i2cm6: i2c@6 {
					#address-cells = <1>;
					#size-cells = <0>;
					reg = <6>;
				};
				i2cm7: i2c@7 {
					#address-cells = <1>;
					#size-cells = <0>;
					reg = <7>;
				};
			};
		};
	};

  fragment@1 {
  		target-path = "/";
  		__overlay__ {
  			aliases {
  				i2c10 = &i2cm0;
          i2c11 = &i2cm1;
  				i2c12 = &i2cm2;
  				i2c13 = &i2cm3;
  				i2c14 = &i2cm4;
  				i2c15 = &i2cm5;
  				i2c16 = &i2cm6;
  				i2c17 = &i2cm7;
  			};
  		};
  	};

	__overrides__ {
		addr = <&pca9548>,"reg:0";
	};
};

The output of dtc -I fs /proc/device-tree

Code: Select all

	aliases {
		intc = "/soc/interrupt-controller@7e00b200";
		i2c10 = "/fragment@0/__overlay__/mux@70/i2c@0";
		spi2 = "/soc/spi@7e2150c0";
		i2c1 = "/soc/i2c@7e804000";
		i2c_vc = "/soc/i2c@7e205000";
		spi0 = "/soc/spi@7e204000";
		thermal = "/soc/thermal";
		vchiq = "/soc/vchiq";
		sdhost = "/soc/sdhost@7e202000";
		aux = "/soc/aux@0x7e215000";
		gpio = "/soc/gpio@7e200000";
		i2c17 = "/fragment@0/__overlay__/mux@70/i2c@7";
		audio = "/soc/audio";
		dma = "/soc/dma@7e007000";
		i2c15 = "/fragment@0/__overlay__/mux@70/i2c@5";
		soc = "/soc";
		leds = "/leds";
		i2c13 = "/fragment@0/__overlay__/mux@70/i2c@3";
		mmc = "/soc/mmc@7e300000";
		serial1 = "/soc/serial@7e215040";
		i2c_arm = "/soc/i2c@7e804000";
		i2c11 = "/fragment@0/__overlay__/mux@70/i2c@1";
		uart0 = "/soc/serial@7e201000";
		fb = "/soc/fb";
		i2c2 = "/soc/i2c@7e805000";
		i2s = "/soc/i2s@7e203000";
		spi1 = "/soc/spi@7e215080";
		usb = "/soc/usb@7e980000";
		i2c0 = "/soc/i2c@7e205000";
		watchdog = "/soc/watchdog@7e100000";
		i2c16 = "/fragment@0/__overlay__/mux@70/i2c@6";
		sound = "/soc/sound";
		i2c14 = "/fragment@0/__overlay__/mux@70/i2c@4";
		mailbox = "/soc/mailbox@7e00b880";
		i2c12 = "/fragment@0/__overlay__/mux@70/i2c@2";
		uart1 = "/soc/serial@7e215040";
		random = "/soc/rng@7e104000";
		i2c = "/soc/i2c@7e804000";
		serial0 = "/soc/serial@7e201000";
	};
The ports I actually got (note i2c-3 is a bit banged port used for the RTC)

Code: Select all

root@piggy:~# ls /dev/i2c*
/dev/i2c-1  /dev/i2c-10  /dev/i2c-11  /dev/i2c-3  /dev/i2c-4  /dev/i2c-5  /dev/i2c-6  /dev/i2c-7  /dev/i2c-8  /dev/i2c-9
I notice that the aliases haven't been dereferenced. It seems like they should have been fixed up at some point to refer to the paths as they actually are in the device tree, and not as they were in the overlay file? Ie they should begin in /soc/blah and not /fragment@0...

Any input appreciated

Steve

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

Re: I2C mulitplexer support

Mon Mar 25, 2019 11:13 am

Conner Labs wrote:
Fri Mar 22, 2019 5:19 pm
The output of dtc -I fs /proc/device-tree

Code: Select all

	aliases {
		intc = "/soc/interrupt-controller@7e00b200";
		i2c10 = "/fragment@0/__overlay__/mux@70/i2c@0";
		spi2 = "/soc/spi@7e2150c0";
		i2c1 = "/soc/i2c@7e804000";
		i2c_vc = "/soc/i2c@7e205000";
		spi0 = "/soc/spi@7e204000";
		thermal = "/soc/thermal";
		vchiq = "/soc/vchiq";
		sdhost = "/soc/sdhost@7e202000";
		aux = "/soc/aux@0x7e215000";
		gpio = "/soc/gpio@7e200000";
		i2c17 = "/fragment@0/__overlay__/mux@70/i2c@7";
		audio = "/soc/audio";
		dma = "/soc/dma@7e007000";
		i2c15 = "/fragment@0/__overlay__/mux@70/i2c@5";
		soc = "/soc";
		leds = "/leds";
		i2c13 = "/fragment@0/__overlay__/mux@70/i2c@3";
		mmc = "/soc/mmc@7e300000";
		serial1 = "/soc/serial@7e215040";
		i2c_arm = "/soc/i2c@7e804000";
		i2c11 = "/fragment@0/__overlay__/mux@70/i2c@1";
		uart0 = "/soc/serial@7e201000";
		fb = "/soc/fb";
		i2c2 = "/soc/i2c@7e805000";
		i2s = "/soc/i2s@7e203000";
		spi1 = "/soc/spi@7e215080";
		usb = "/soc/usb@7e980000";
		i2c0 = "/soc/i2c@7e205000";
		watchdog = "/soc/watchdog@7e100000";
		i2c16 = "/fragment@0/__overlay__/mux@70/i2c@6";
		sound = "/soc/sound";
		i2c14 = "/fragment@0/__overlay__/mux@70/i2c@4";
		mailbox = "/soc/mailbox@7e00b880";
		i2c12 = "/fragment@0/__overlay__/mux@70/i2c@2";
		uart1 = "/soc/serial@7e215040";
		random = "/soc/rng@7e104000";
		i2c = "/soc/i2c@7e804000";
		serial0 = "/soc/serial@7e201000";
	};
The ports I actually got (note i2c-3 is a bit banged port used for the RTC)

Code: Select all

root@piggy:~# ls /dev/i2c*
/dev/i2c-1  /dev/i2c-10  /dev/i2c-11  /dev/i2c-3  /dev/i2c-4  /dev/i2c-5  /dev/i2c-6  /dev/i2c-7  /dev/i2c-8  /dev/i2c-9
I notice that the aliases haven't been dereferenced. It seems like they should have been fixed up at some point to refer to the paths as they actually are in the device tree, and not as they were in the overlay file? Ie they should begin in /soc/blah and not /fragment@0...
So dtc is only compiling the overlay, not the full device-tree, and I don't believe it even knows for definite that it is compiling a fragment.
It therefore sees you "&i2cm0;" and looks it up based on what it knows, hence "fragment@0....".

Whilst not as portable, you can set absolute paths in the aliases, so

Code: Select all

        fragment@1 {
                target-path = "/";
                __overlay__ {
                        aliases {
                                i2c10 = "/soc/i2c@7e804000/mux@70/i2c@0";
                                i2c11 = "/soc/i2c@7e804000/mux@70/i2c@1";
                                i2c12 = "/soc/i2c@7e804000/mux@70/i2c@2";
                                i2c13 = "/soc/i2c@7e804000/mux@70/i2c@3";
                                i2c14 = "/soc/i2c@7e804000/mux@70/i2c@4";
                                i2c15 = "/soc/i2c@7e804000/mux@70/i2c@5";
                                i2c16 = "/soc/i2c@7e804000/mux@70/i2c@6";
                                i2c17 = "/soc/i2c@7e804000/mux@70/i2c@7";
                        };
                };
        };
works for me to give

Code: Select all

pi@raspberrypi:~/tmp $ ls /dev/i2c*
/dev/i2c-0  /dev/i2c-1  /dev/i2c-10  /dev/i2c-11  /dev/i2c-12  /dev/i2c-13  /dev/i2c-14  /dev/i2c-15  /dev/i2c-16  /dev/i2c-17
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.

Conner Labs
Posts: 45
Joined: Fri Jan 11, 2013 2:45 pm
Location: Glasgow
Contact: Website

Re: I2C mulitplexer support

Mon Mar 25, 2019 5:40 pm

Thanks. What would be the "best" way to handle this? Should I compile my new overlays together with the rest of device tree, to give it a chance to find the references?

As for portability: can I take for granted that "i2c@7e804000" will be i2c_arm on the various Raspberry Pi products we use? I expect this will be deployed on the CM3 and CM3+.

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

Re: I2C mulitplexer support

Mon Mar 25, 2019 6:06 pm

Conner Labs wrote:
Mon Mar 25, 2019 5:40 pm
Thanks. What would be the "best" way to handle this? Should I compile my new overlays together with the rest of device tree, to give it a chance to find the references?

As for portability: can I take for granted that "i2c@7e804000" will be i2c_arm on the various Raspberry Pi products we use? I expect this will be deployed on the CM3 and CM3+.
Compiling into the base DT probably becomes worse in terms of portability. Should a later kernel update a DT compatible string, you've now got bigger problems that can be tricky to track down.

i2c@7e804000 will always be BSC1.
On some original model B's BSC1 was used by the VPU, but all models since have assigned it as i2c_arm.
CM/CM3/CM3+ will still assign i2c_arm the same way.
It's possible that future products may change the node, but I can't foretell that.

It's possible there's a way to fix it up better in the compiler or dtoverlay, but that's one for PhilE.
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 “Interfacing (DSI, CSI, I2C, etc.)”