diff mbox

[RFC,v2,2/4] dt-bindings: i2c: mux: demux-pinctrl: add bindings

Message ID 1452088285-6427-3-git-send-email-wsa@the-dreams.de
State Changes Requested, archived
Headers show

Commit Message

Wolfram Sang Jan. 6, 2016, 1:51 p.m. UTC
From: Wolfram Sang <wsa+renesas@sang-engineering.com>

These bindings allow an I2C bus to switch between multiple masters. This
is not hot-swichting because connected I2C slaves will be
re-instantiated. It is meant to select the best I2C core at runtime once
the task is known. Example: Prefer i2c-gpio over another I2C core
because of HW errata affetcing your use case.

Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
---
 .../devicetree/bindings/i2c/i2c-demux-pinctrl.txt  | 155 +++++++++++++++++++++
 1 file changed, 155 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/i2c/i2c-demux-pinctrl.txt

Comments

Geert Uytterhoeven Jan. 6, 2016, 2:30 p.m. UTC | #1
Hi Wolfram,

On Wed, Jan 6, 2016 at 2:51 PM, Wolfram Sang <wsa@the-dreams.de> wrote:
> These bindings allow an I2C bus to switch between multiple masters. This
> is not hot-swichting because connected I2C slaves will be
> re-instantiated. It is meant to select the best I2C core at runtime once
> the task is known. Example: Prefer i2c-gpio over another I2C core
> because of HW errata affetcing your use case.

> --- /dev/null
> +++ b/Documentation/devicetree/bindings/i2c/i2c-demux-pinctrl.txt
> @@ -0,0 +1,155 @@

> +Here is a snipplet for a bus to be demuxed. It contains various i2c clients for

snippet

> +HDMI, so the bus is named "i2c-hdmi":
> +
> +       i2chdmi: i2c@8 {

Would it make sense to call the node "i2c-bus@8"?
> +
> +               compatible = "i2c-demux-pinctrl";
> +               i2c-parent = <&gpioi2c>, <&iic2>, <&i2c2>;

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jan Lübbe Jan. 7, 2016, 4:56 p.m. UTC | #2
Hi Wolfram,

On Mi, 2016-01-06 at 14:51 +0100, Wolfram Sang wrote:
[...]
> +Required properties:
> +- compatible: "i2c-demux-pinctrl"
> +- i2c-parent: List of phandles of I2C masters available for selection. The first
> +	      one will be used as default.
> +- i2c-bus-name: The name of this bus. Also needed as pinctrl-name for the I2C
> +		parents.
[...]
> +	i2chdmi: i2c@8 {
> +		compatible = "i2c-demux-pinctrl";
> +		i2c-parent = <&gpioi2c>, <&iic2>, <&i2c2>;
> +		i2c-bus-name = "i2c-hdmi";
> +		#address-cells = <1>;
> +		#size-cells = <0>;
[...]
> +	gpioi2c: i2c@9 {
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		compatible = "i2c-gpio";
[...]
> +&i2c2	{
> +	pinctrl-0 = <&i2c2_pins>;
> +	pinctrl-names = "i2c-hdmi";
> +
> +	clock-frequency = <100000>;
> +};
[...]
> +&iic2	{
> +	pinctrl-0 = <&iic2_pins>;
> +	pinctrl-names = "i2c-hdmi";
> +
> +	clock-frequency = <100000>;
> +};
[...]

It seems that the demux-pinctrl driver reconfigures the pinctrl settings
for the parent devices. I would have expected to have alternative
pinctrl state on the demux node support switching the same external pins
between the different controllers. Wouldn't it be possible to have
pinctrl conflicts between &i2c2_pins and &iic2_pins otherwise?

Regards,
Jan
Rob Herring Jan. 11, 2016, 2:52 a.m. UTC | #3
On Wed, Jan 06, 2016 at 02:51:23PM +0100, Wolfram Sang wrote:
> From: Wolfram Sang <wsa+renesas@sang-engineering.com>
> 
> These bindings allow an I2C bus to switch between multiple masters. This
> is not hot-swichting because connected I2C slaves will be

s/swichting/switching/

> re-instantiated. It is meant to select the best I2C core at runtime once
> the task is known. Example: Prefer i2c-gpio over another I2C core
> because of HW errata affetcing your use case.

This seems okay to me. I don't like not having the i2c devices under the 
i2c controller, but not really much we can do about that.

I have another usecase which might end up needing a similar structure 
as this. That is the whole question of how to deal with capes, hats, 
shields and various daughterboards. For I2C devices on a daughterboard, 
we need to be able to have a DT overlay for the daughterboard described 
in terms of the connector(s) and independent of the host. Then the 
base DT needs to define the mapping from the connector to the host 
controller. A complicating factor would be having devices on the same 
bus but split across the main and daughter boards. I don't see anything 
specific to change here, but just want to throw that out.

[...]

> +
> +Changing I2C controllers:
> +
> +The created mux-device will have a file "cur_master" in its sysfs-entry. Write
> +0 there for the first master listed in the "i2c-parent" property, 1 for the
> +second etc. Reading the file will give you a list with the active master
> +marked. Example from a Renesas Lager board:

This is Linux specific and should not be in the binding. You also need 
sysfs docs for these sysfs files.

Rob
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Geert Uytterhoeven Jan. 11, 2016, 8:01 a.m. UTC | #4
Hi Rob,

On Mon, Jan 11, 2016 at 3:52 AM, Rob Herring <robh@kernel.org> wrote:
> On Wed, Jan 06, 2016 at 02:51:23PM +0100, Wolfram Sang wrote:
>> From: Wolfram Sang <wsa+renesas@sang-engineering.com>
>>
>> These bindings allow an I2C bus to switch between multiple masters. This
>> is not hot-swichting because connected I2C slaves will be
>
> s/swichting/switching/
>
>> re-instantiated. It is meant to select the best I2C core at runtime once
>> the task is known. Example: Prefer i2c-gpio over another I2C core
>> because of HW errata affetcing your use case.
>
> This seems okay to me. I don't like not having the i2c devices under the
> i2c controller, but not really much we can do about that.
>
> I have another usecase which might end up needing a similar structure
> as this. That is the whole question of how to deal with capes, hats,
> shields and various daughterboards. For I2C devices on a daughterboard,
> we need to be able to have a DT overlay for the daughterboard described
> in terms of the connector(s) and independent of the host. Then the
> base DT needs to define the mapping from the connector to the host

Indeed. Currently an i2c bus is described in DT as tied to an i2c controller,
while physically it's tied to a bunch of pins. Tying the bus to a controller
is done through pinctrl.

> controller. A complicating factor would be having devices on the same
> bus but split across the main and daughter boards. I don't see anything
> specific to change here, but just want to throw that out.

Can't the daughter board DTS just add more child devices to the mainboard bus?

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Wolfram Sang Jan. 13, 2016, 12:52 p.m. UTC | #5
On Wed, Jan 06, 2016 at 03:30:39PM +0100, Geert Uytterhoeven wrote:
> Hi Wolfram,
> 
> On Wed, Jan 6, 2016 at 2:51 PM, Wolfram Sang <wsa@the-dreams.de> wrote:
> > These bindings allow an I2C bus to switch between multiple masters. This
> > is not hot-swichting because connected I2C slaves will be
> > re-instantiated. It is meant to select the best I2C core at runtime once
> > the task is known. Example: Prefer i2c-gpio over another I2C core
> > because of HW errata affetcing your use case.
> 
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/i2c/i2c-demux-pinctrl.txt
> > @@ -0,0 +1,155 @@
> 
> > +Here is a snipplet for a bus to be demuxed. It contains various i2c clients for
> 
> snippet
> 
> > +HDMI, so the bus is named "i2c-hdmi":
> > +
> > +       i2chdmi: i2c@8 {
> 
> Would it make sense to call the node "i2c-bus@8"?

That sounds like a question for our EPapr expert Sergei (CCed) :)

> > +
> > +               compatible = "i2c-demux-pinctrl";
> > +               i2c-parent = <&gpioi2c>, <&iic2>, <&i2c2>;
> 
> Gr{oetje,eeting}s,
> 
>                         Geert
> 
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
> 
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
>                                 -- Linus Torvalds
Wolfram Sang Jan. 13, 2016, 1:02 p.m. UTC | #6
Hi Jan,

> > +Required properties:
> > +- compatible: "i2c-demux-pinctrl"
> > +- i2c-parent: List of phandles of I2C masters available for selection. The first
> > +	      one will be used as default.
> > +- i2c-bus-name: The name of this bus. Also needed as pinctrl-name for the I2C
> > +		parents.
> [...]
> > +	i2chdmi: i2c@8 {
> > +		compatible = "i2c-demux-pinctrl";
> > +		i2c-parent = <&gpioi2c>, <&iic2>, <&i2c2>;
> > +		i2c-bus-name = "i2c-hdmi";
> > +		#address-cells = <1>;
> > +		#size-cells = <0>;
> [...]
> > +	gpioi2c: i2c@9 {
> > +		#address-cells = <1>;
> > +		#size-cells = <0>;
> > +		compatible = "i2c-gpio";
> [...]
> > +&i2c2	{
> > +	pinctrl-0 = <&i2c2_pins>;
> > +	pinctrl-names = "i2c-hdmi";
> > +
> > +	clock-frequency = <100000>;
> > +};
> [...]
> > +&iic2	{
> > +	pinctrl-0 = <&iic2_pins>;
> > +	pinctrl-names = "i2c-hdmi";
> > +
> > +	clock-frequency = <100000>;
> > +};
> [...]
> 
> It seems that the demux-pinctrl driver reconfigures the pinctrl settings
> for the parent devices. I would have expected to have alternative
> pinctrl state on the demux node support switching the same external pins
> between the different controllers. Wouldn't it be possible to have
> pinctrl conflicts between &i2c2_pins and &iic2_pins otherwise?

I don't think so. Before i2c2 is enabled, iic2 gets disabled (status =
"disabled" via OF_DYNAMIC) and thus the pins get free. Doing it this
way, you could even have something like this:

	pinctrl-0 = <&iic2_pins>, <&iic2_c_pins>;
	pinctrl-names = "i2c-hdmi", "i2c-sensors";

which allows you to demux this controller to this or that bus. I haven't
tested this, though.

   Wolfram
Sergei Shtylyov Jan. 13, 2016, 2:07 p.m. UTC | #7
Hello.

On 01/13/2016 03:52 PM, Wolfram Sang wrote:

>>> These bindings allow an I2C bus to switch between multiple masters. This
>>> is not hot-swichting because connected I2C slaves will be
>>> re-instantiated. It is meant to select the best I2C core at runtime once
>>> the task is known. Example: Prefer i2c-gpio over another I2C core
>>> because of HW errata affetcing your use case.
>>
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/i2c/i2c-demux-pinctrl.txt
>>> @@ -0,0 +1,155 @@
>>
>>> +Here is a snipplet for a bus to be demuxed. It contains various i2c clients for
>>
>> snippet
>>
>>> +HDMI, so the bus is named "i2c-hdmi":
>>> +
>>> +       i2chdmi: i2c@8 {
>>
>> Would it make sense to call the node "i2c-bus@8"?
>
> That sounds like a question for our EPapr expert Sergei (CCed) :)

    ePAPR only mentions "i2c". I'm not sure where the numeric part of the name 
comes from in this case...

[...]

MBR, Sergei

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/Documentation/devicetree/bindings/i2c/i2c-demux-pinctrl.txt b/Documentation/devicetree/bindings/i2c/i2c-demux-pinctrl.txt
new file mode 100644
index 00000000000000..de571be68f4754
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/i2c-demux-pinctrl.txt
@@ -0,0 +1,155 @@ 
+Pinctrl-based I2C Bus DeMux
+
+This binding describes an I2C bus demultiplexer that uses pin multiplexing to
+route the I2C signals, and represents the pin multiplexing configuration using
+the pinctrl device tree bindings. This may be used to select one I2C IP core at
+runtime which may have a better feature set for a given task than another I2C
+IP core on the SoC. The most simple example is to fall back to GPIO bitbanging
+if your current runtime configuration hits an errata of the internal IP core.
+
+    +-------------------------------+
+    | SoC                           |
+    |                               |   +-----+  +-----+
+    |   +------------+              |   | dev |  | dev |
+    |   |I2C IP Core1|--\           |   +-----+  +-----+
+    |   +------------+   \-------+  |      |        |
+    |                    |Pinctrl|--|------+--------+
+    |   +------------+   +-------+  |
+    |   |I2C IP Core2|--/           |
+    |   +------------+              |
+    |                               |
+    +-------------------------------+
+
+Required properties:
+- compatible: "i2c-demux-pinctrl"
+- i2c-parent: List of phandles of I2C masters available for selection. The first
+	      one will be used as default.
+- i2c-bus-name: The name of this bus. Also needed as pinctrl-name for the I2C
+		parents.
+
+Furthermore, I2C mux properties and child nodes. See mux.txt in this directory.
+
+Example:
+
+Here is a snipplet for a bus to be demuxed. It contains various i2c clients for
+HDMI, so the bus is named "i2c-hdmi":
+
+	i2chdmi: i2c@8 {
+
+		compatible = "i2c-demux-pinctrl";
+		i2c-parent = <&gpioi2c>, <&iic2>, <&i2c2>;
+		i2c-bus-name = "i2c-hdmi";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ak4643: sound-codec@12 {
+			compatible = "asahi-kasei,ak4643";
+
+			#sound-dai-cells = <0>;
+			reg = <0x12>;
+		};
+
+		composite-in@20 {
+			compatible = "adi,adv7180";
+			reg = <0x20>;
+			remote = <&vin1>;
+
+			port {
+				adv7180: endpoint {
+					bus-width = <8>;
+					remote-endpoint = <&vin1ep0>;
+				};
+			};
+		};
+
+		hdmi@39 {
+			compatible = "adi,adv7511w";
+			reg = <0x39>;
+			interrupt-parent = <&gpio1>;
+			interrupts = <15 IRQ_TYPE_LEVEL_LOW>;
+
+			adi,input-depth = <8>;
+			adi,input-colorspace = "rgb";
+			adi,input-clock = "1x";
+			adi,input-style = <1>;
+			adi,input-justification = "evenly";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					adv7511_in: endpoint {
+						remote-endpoint = <&du_out_lvds0>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					adv7511_out: endpoint {
+						remote-endpoint = <&hdmi_con>;
+					};
+				};
+			};
+		};
+	};
+
+And for clarification, here are the snipplets for the i2c-parents:
+
+	gpioi2c: i2c@9 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "i2c-gpio";
+		status = "disabled";
+		gpios = <&gpio5 6 GPIO_ACTIVE_HIGH /* sda */
+			 &gpio5 5 GPIO_ACTIVE_HIGH /* scl */
+			>;
+		i2c-gpio,delay-us = <5>;
+	};
+
+...
+
+&i2c2	{
+	pinctrl-0 = <&i2c2_pins>;
+	pinctrl-names = "i2c-hdmi";
+
+	clock-frequency = <100000>;
+};
+
+...
+
+&iic2	{
+	pinctrl-0 = <&iic2_pins>;
+	pinctrl-names = "i2c-hdmi";
+
+	clock-frequency = <100000>;
+};
+
+Please note:
+
+- pinctrl properties for the parent I2C controllers need a pinctrl state
+  with the same name as i2c-bus-name, not "default"!
+
+- the i2c masters must have their status "disabled". This driver will
+  enable them at runtime when needed.
+
+Changing I2C controllers:
+
+The created mux-device will have a file "cur_master" in its sysfs-entry. Write
+0 there for the first master listed in the "i2c-parent" property, 1 for the
+second etc. Reading the file will give you a list with the active master
+marked. Example from a Renesas Lager board:
+
+root@Lager:~# cat /sys/bus/platform/devices/i2c@8/cur_master
+* 0 - /i2c@9
+  1 - /i2c@e6520000
+  2 - /i2c@e6530000
+
+root@Lager:~# echo 2 > /sys/bus/platform/devices/i2c@8/cur_master
+
+root@Lager:~# cat /sys/bus/platform/devices/i2c@8/cur_master
+  0 - /i2c@9
+  1 - /i2c@e6520000
+* 2 - /i2c@e6530000
+