Multiple ic2 muxes in a device tree

Mitch Bradley wmb at firmworks.com
Wed May 11 07:00:53 EST 2011


I don't know much about how Linux handles i2c hierarchies, but I can speak with some authority about how it the device tree "should" be structured in order to conform to the principles already established for other buses.

Note that *each* pca9547 results in a subtree of the form:

   i2cmux {
      i2c at 0 { }
      i2c at 1 { }
      i2c at 2 { }
      i2c at 3 { }
      i2c at 4 { }
      i2c at 5 { }
      i2c at 6 { }
      i2c at 7 { }
   }

Each of those 8 "i2c" children represents a complete I2C bus.  When a subordinate pca9547 is connected to one of those buses, the hierarchy expands to:

   i2cmux {
      i2c at 0 { 
         i2cmux {
            i2c at 0 { }
            i2c at 1 { }
            i2c at 2 { }
            i2c at 3 { }
            i2c at 4 { }
            i2c at 5 { }
            i2c at 6 { }
            i2c at 7 { }
         }
      }
      i2c at 1 { }
      i2c at 2 { }
      i2c at 3 { }
      i2c at 4 { }
      i2c at 5 { }
      i2c at 6 { }
      i2c at 7 { }
   }

The full device tree representation for the hardware shown below would be:

i2c at 3100 {
  #address-cells = <1>;
  #size-cells = <0>;
  cell-index = <1>;
  compatible = "fsl-i2c";
  reg = <0x3100 0x100>;
  interrupts = <15 0x8>;
  interrupt-parent = <&ipic>;
  dfsrr;
  temp-sensor at 49 {
    compatible = "national,lm73";
    reg = <0x49>;
  };
  eeprom at 54 {
    compatible = "at24,24c02";
    reg = <0x54>;
    pagesize = <4>;
  };
  i2cmux at 77 {
    #address-cells = <1>;
    #size-cells = <0>;
    compatible = "philips,pca9547";
    reg = <0x77>;
    i2c at 0 {
      #address-cells = <1>;
      #size-cells = <0>;
      compatible = "philips,pca9547-channel";
      reg = <0>;
      i2cmux at 70 {
        #address-cells = <1>;
        #size-cells = <0>;
        compatible = "philips,pca9547";
        reg = <0x70>;
        {Potentially 8 Subordinate nodes, each named "i2c", with children}
      }
    };
    i2c at 1 {
      #address-cells = <1>;
      #size-cells = <0>;
      compatible = "philips,pca9547-channel";
      reg = <1>;
      i2cmux at 71 {
        #address-cells = <1>;
        #size-cells = <0>;
        compatible = "philips,pca9547";
        reg = <0x71>;
         {Potentially 8 Subordinate nodes, each named "i2c", with children}
      };
    };
    i2c at 2 {
      #address-cells = <1>;
      #size-cells = <0>;
      compatible = "philips,pca9547-channel";
      reg = <2>;
      i2cmux at 72 {
        #address-cells = <1>;
        #size-cells = <0>;
        compatible = "philips,pca9547";
        reg = <0x72>;
        {Potentially 8 Subordinate nodes, each named "i2c", with children}
      };
    i2c at 3 {
      #address-cells = <1>;
      #size-cells = <0>;
      compatible = "philips,pca9547-channel";
      reg = <3>;
      i2cmux at 73 {
        #address-cells = <1>;
        #size-cells = <0>;
        compatible = "philips,pca9547";
        reg = <0x73>;
        {Potentially 8 Subordinate nodes, each named "i2c", with children}
      };
    i2c at 4 {
      #address-cells = <1>;
      #size-cells = <0>;
      compatible = "philips,pca9547-channel";
      reg = <4>;
      i2cmux at 74 {
        #address-cells = <1>;
        #size-cells = <0>;
        compatible = "philips,pca9547";
        reg = <0x74>;
        {Potentially 8 Subordinate nodes, each named "i2c", with children}
      };
    };
    i2c at 5 {
      #address-cells = <1>;
      #size-cells = <0>;
      compatible = "philips,pca9547-channel";
      reg = <5>;
      i2cmux at 75 {
        #address-cells = <1>;
        #size-cells = <0>;
        compatible = "philips,pca9547";
        reg = <0x75>;
        {Potentially 8 Subordinate nodes, each named "i2c", with children}
      };
    i2c at 6 {
      #address-cells = <1>;
      #size-cells = <0>;
      compatible = "philips,pca9547-channel";
      reg = <6>;
      rtc at 68 {
        compatible = "stm,m41st85";
        reg = <0x68>;
      };
    };
    i2c at 7 {
      #address-cells = <1>;
      #size-cells = <0>;
      compatible = "philips,pca9547-channel";
      reg = <7>;
      temp-sensor at 48 {
        compatible = "national,lm73";
        reg = <0x48>;
      };
    };
  };
};


I understand the temptation to collapse the hierarchy by combining the mux node with its subordinate buses (using 2 address cells), but in my experience, shortcuts like that have not aged well.  The case where a single-level hierarchy would work would be a simple i2c-to-i2c bridge with only one child bus.  In this case, the existence of multiple independent child buses argues for the two-level hierarchy, satisfying the following requirements:

a) From the standpoint of a parent bus "looking down" at a pca9547, the pca9547 appears to be a single device at a well-defined address.

b) From the standpoint of a child device "looking up" at a pca9547, that child is attached to a specific I2C bus with a standard one-cell I2C address space.

Again, though, I'm unsure that this "correct" hierarchy is compatible with the expectations of Linux drivers.

On 5/10/2011 9:24 AM, James Baldwin wrote:
> I have tried many different combinations based on what I’ve been able to 
> find on
> 
> the internet over the last week and have reached a dead end.
> 
> I have the following i2c topology and specify the devices as follows: 
> Linux 2.6.38.5
> 
> only seems to recognize the devices connected directly to the i2c 
> controller when it boots.
> 
> I can add the muxes and lm73/m41st85 manually using the echo command 
> from the console:
> 
> “echo pca9547 0x70 > /sys/bus/12c/devices/i2c-2/new_device”
> 
> This tells me I have three prime candidates for potential issues.
> 
> 1)The device tree specification is incorrect
> 
> 2)The device tree processing is incorrect (It is ‘appears’
> correct in the /proc/devicetree hierarchy)
> 
> 3)The probing code for i2c devices doesn’t currently traverse muxes 
> properly.
> 
> As validating the device tree should be the simplest to eliminate (and 
> is the part I’m
> 
> Directly involved with), I’d appreciate any Constructive comments on 
> solving this problem.
> 
> |
> 
> i2c ctrl ----|
> 
> |---lm73 at 0x49
> 
> |
> 
> |---24c02 at 0x54
> 
> |
> 
> |---pca9547 at 0x77---|
> 
> | |-Chan 0---|---pca9547 at 0x70
> 
> | | |
> 
> | |
> 
> | |-Chan 1---|---pca9547 at 0x71
> 
> | | |
> 
> | |
> 
> | |-Chan 2---|---pca9547 at 0x72
> 
> | | |
> 
> | |
> 
> | |-Chan 3---|---pca9547 at 0x73
> 
> | | |
> 
> | |
> 
> | |-Chan 4---|---pca9547 at 0x74
> 
> | | |
> 
> | |
> 
> | |-Chan 5---|---pca9547 at 0x75
> 
> | | |
> 
> | |
> 
> | |-Chan 6---|---m41st85 at 0x68
> 
> | |
> 
> | |-Chan 7---|---lm73 at 0x48
> 
> | |
> 
> i2c at 3100 {
> 
> #address-cells = <1>;
> 
> #size-cells = <0>;
> 
> cell-index = <1>;
> 
> compatible = "fsl-i2c";
> 
> reg = <0x3100 0x100>;
> 
> interrupts = <15 0x8>;
> 
> interrupt-parent = <&ipic>;
> 
> dfsrr;
> 
> temp-sensor at 49 {
> 
> compatible = "national,lm73";
> 
> reg = <0x49>;
> 
> };
> 
> eeprom at 54 {
> 
> compatible = "at24,24c02";
> 
> reg = <0x54>;
> 
> pagesize = <4>;
> 
> };
> 
> mux at 77 {
> 
> #address-cells = <2>;
> 
> #size-cells = <0>;
> 
> compatible = "philips,pca9547";
> 
> reg = <0x77>;
> 
> mux at 0,70 {
> 
> #address-cells = <2>;
> 
> #size-cells = <0>;
> 
> compatible = "philips,pca9547";
> 
> reg = <0 0x70>;
> 
> };
> 
> mux at 0,71 {
> 
> #address-cells = <2>;
> 
> #size-cells = <0>;
> 
> compatible = "philips,pca9547";
> 
> reg = <1 0x71>;
> 
> };
> 
> mux at 0,72 {
> 
> #address-cells = <2>;
> 
> #size-cells = <0>;
> 
> compatible = "philips,pca9547";
> 
> reg = <2 0x72>;
> 
> };
> 
> mux at 0,73 {
> 
> #address-cells = <2>;
> 
> #size-cells = <0>;
> 
> compatible = "philips,pca9547";
> 
> reg = <3 0x73>;
> 
> };
> 
> mux at 0,74 {
> 
> #address-cells = <2>;
> 
> #size-cells = <0>;
> 
> compatible = "philips,pca9547";
> 
> reg = <4 0x74>;
> 
> };
> 
> mux at 0,75 {
> 
> #address-cells = <2>;
> 
> #size-cells = <0>;
> 
> compatible = "philips,pca9547";
> 
> reg = <0 0x75>;
> 
> };
> 
> temp-sensor at 7,48 {
> 
> compatible = "national,lm73";
> 
> reg = <7 0x48 >;
> 
> };
> 
> rtc at 6,68 {
> 
> compatible = "stm,m41st85";
> 
> reg = <6 0x68>;
> 
> };
> 
> };
> 
> };
> 
> Thanks,
> 
> Jim Baldwin
> 
> 
> 
> *NOTICE:*This email and any files transmitted with it are Enablence 
> confidential and intended solely for the use of the individual or entity 
> to whom they are addressed. If you have received this email in error 
> please notify the sender. This message contains Enablence confidential 
> information and is intended only for the individual named. If you are 
> not the named addressee you should not disseminate, distribute or copy 
> this e-mail. Please notify the sender immediately by e-mail if you have 
> received this e-mail by mistake and delete this e-mail from your system. 
> If you are not the intended recipient you are notified that disclosing, 
> copying, distributing or taking any action in reliance on the contents 
> of this information is strictly prohibited.
> 
> 
> 
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss at lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss


More information about the devicetree-discuss mailing list