Tegra's I2C driver has a unique feature built in (although not mainlined yet); it can multiplex the I2C bus onto different sets of pins using the Tegra pinmux module, and hence can register more than 1 I2C bus with the I2C core for each controller. The exact number of busses registers, and the pinmux settings to be used, are provided by platform data. See:
http://git.chromium.org/git/kernel-next.git chromeos-2.6.38 include/linux/i2c-tegra.h arch/arm/mach-tegra/board-seaboard.c
If I understand the direction of devicetree on ARM, there should be a single devicetree node for the Tegra I2C controller, which will get matched up with a static platform device registration in e.g. mach-tegra/board-dt.c
I can easily see how to provide the appropriate platform data to the Tegra I2C driver, by definining the appropriate fields in a custom devicetree binding.
To cater for the multiple child busses, the simplest solution seems to be to define each child node's reg property to be a tuple, <sub_bus_id, i2c_address> (c.f. existing <i2c_address>). E.g.:
IIC0: i2c@00000000 { compatible = "nvidia,tegra250-iic"; #address-cells = <2>; #size-cells = <0>; bus_muxes = <pinmuxid_1 pinmux_value_1 pinmuxid_2 pinmux_value_2>; rtc@68 { compatible = "stm,m41t80"; reg = <0 0x68>; }; sttm@48 { compatible = "ad,ad7414"; reg = <1 0x48>; }; };
The problem is then that of_i2c_register_devices won't work well for the Tegra I2C controller, since it enforces that each child node's reg property be a single value, the I2C address.
To solve this, should we:
a) Have each mux'd bus have a separate devicetree node underneath the main I2C device, e.g.:
IIC0: i2c@00000000 { compatible = "nvidia,tegra250-iic"; // @0 doesn't really end up matching a // reg property within the child though bus@0 { #address-cells = <1>; #size-cells = <0>; pinmux_group = <N>; pinmux_value = <M>;
rtc@68 { compatible = "stm,m41t80"; reg = <0x68>; }; }
bus@1 { #address-cells = <1>; #size-cells = <0>; pinmux_group = <N>; pinmux_value = <M>;
sttm@48 { compatible = "ad,ad7414"; reg = <0x48>; }; } };
Then, the bus@0 or bus@1 nodes could be placed into adap->dev.of_node, since the devices are hung off there.
b)
Implement custom devicetree child enumeration code in the Tegra I2C driver to replace of_i2c_register_devices, which implements the two-entry reg format. The first devicetree example in this email could then be used.
c)
Perhaps remove the bus mux functionality from the Tegra I2C driver, and implement a separate I2C mux driver for it.
I'm not sure if devicetree has a defined representation for I2C bus muxes, and even if it does, since the mux control isn't accessed by I2C registers (as most standalone I2C bus muxes are), but rather Tegra- specific pinmux API calls, I'm not quite sure how to represent it in device-tree.
Thanks for any thoughts!