Commit bc45449b1444611d68466ae7f45f235420d79019
Committed by
Wolfram Sang
1 parent
5a3ecd5f98
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
i2c/of: Automatically populate i2c mux busses from device tree data.
For 'normal' i2c bus drivers, we can call of_i2c_register_devices() and have the device tree framework automatically populate the bus with the devices specified in the device tree. This patch adds a common code to the i2c mux framework to have the mux sub-busses be populated by the of_i2c_register_devices() too. If the mux device has an of_node, we populate the sub-bus' of_node so that the subsequent call to of_i2c_register_devices() will find the corresponding devices. It seemed better to put this logic in i2c_add_mux_adapter() rather than the individual mux drivers, as they will all probably want to do the same thing. Signed-off-by: David Daney <david.daney@cavium.com> Acked-by: Stephen Warren <swarren@wwwdotorg.org> Tested-by: Lars-Peter Clausen <lars@metafoo.de> [wsa: removed superfluous ret-variable and fixed a typo in a comment] Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
Showing 2 changed files with 83 additions and 0 deletions Side-by-side Diff
Documentation/devicetree/bindings/i2c/mux.txt
1 | +Common i2c bus multiplexer/switch properties. | |
2 | + | |
3 | +An i2c bus multiplexer/switch will have several child busses that are | |
4 | +numbered uniquely in a device dependent manner. The nodes for an i2c bus | |
5 | +multiplexer/switch will have one child node for each child | |
6 | +bus. | |
7 | + | |
8 | +Required properties: | |
9 | +- #address-cells = <1>; | |
10 | +- #size-cells = <0>; | |
11 | + | |
12 | +Required properties for child nodes: | |
13 | +- #address-cells = <1>; | |
14 | +- #size-cells = <0>; | |
15 | +- reg : The sub-bus number. | |
16 | + | |
17 | +Optional properties for child nodes: | |
18 | +- Other properties specific to the multiplexer/switch hardware. | |
19 | +- Child nodes conforming to i2c bus binding | |
20 | + | |
21 | + | |
22 | +Example : | |
23 | + | |
24 | + /* | |
25 | + An NXP pca9548 8 channel I2C multiplexer at address 0x70 | |
26 | + with two NXP pca8574 GPIO expanders attached, one each to | |
27 | + ports 3 and 4. | |
28 | + */ | |
29 | + | |
30 | + mux@70 { | |
31 | + compatible = "nxp,pca9548"; | |
32 | + reg = <0x70>; | |
33 | + #address-cells = <1>; | |
34 | + #size-cells = <0>; | |
35 | + | |
36 | + i2c@3 { | |
37 | + #address-cells = <1>; | |
38 | + #size-cells = <0>; | |
39 | + reg = <3>; | |
40 | + | |
41 | + gpio1: gpio@38 { | |
42 | + compatible = "nxp,pca8574"; | |
43 | + reg = <0x38>; | |
44 | + #gpio-cells = <2>; | |
45 | + gpio-controller; | |
46 | + }; | |
47 | + }; | |
48 | + i2c@4 { | |
49 | + #address-cells = <1>; | |
50 | + #size-cells = <0>; | |
51 | + reg = <4>; | |
52 | + | |
53 | + gpio2: gpio@38 { | |
54 | + compatible = "nxp,pca8574"; | |
55 | + reg = <0x38>; | |
56 | + #gpio-cells = <2>; | |
57 | + gpio-controller; | |
58 | + }; | |
59 | + }; | |
60 | + }; |
drivers/i2c/i2c-mux.c
... | ... | @@ -24,6 +24,8 @@ |
24 | 24 | #include <linux/slab.h> |
25 | 25 | #include <linux/i2c.h> |
26 | 26 | #include <linux/i2c-mux.h> |
27 | +#include <linux/of.h> | |
28 | +#include <linux/of_i2c.h> | |
27 | 29 | |
28 | 30 | /* multiplexer per channel data */ |
29 | 31 | struct i2c_mux_priv { |
... | ... | @@ -125,6 +127,25 @@ |
125 | 127 | priv->adap.algo_data = priv; |
126 | 128 | priv->adap.dev.parent = &parent->dev; |
127 | 129 | |
130 | + /* | |
131 | + * Try to populate the mux adapter's of_node, expands to | |
132 | + * nothing if !CONFIG_OF. | |
133 | + */ | |
134 | + if (mux_dev->of_node) { | |
135 | + struct device_node *child; | |
136 | + u32 reg; | |
137 | + | |
138 | + for_each_child_of_node(mux_dev->of_node, child) { | |
139 | + ret = of_property_read_u32(child, "reg", ®); | |
140 | + if (ret) | |
141 | + continue; | |
142 | + if (chan_id == reg) { | |
143 | + priv->adap.dev.of_node = child; | |
144 | + break; | |
145 | + } | |
146 | + } | |
147 | + } | |
148 | + | |
128 | 149 | if (force_nr) { |
129 | 150 | priv->adap.nr = force_nr; |
130 | 151 | ret = i2c_add_numbered_adapter(&priv->adap); |
... | ... | @@ -141,6 +162,8 @@ |
141 | 162 | |
142 | 163 | dev_info(&parent->dev, "Added multiplexed i2c bus %d\n", |
143 | 164 | i2c_adapter_id(&priv->adap)); |
165 | + | |
166 | + of_i2c_register_devices(&priv->adap); | |
144 | 167 | |
145 | 168 | return &priv->adap; |
146 | 169 | } |