Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

of: i2c: Add i2c-mux-idle-disconnect DT property to PCA954x mux driver

Add i2c-mux-idle-disconnect device tree property to PCA954x mux driver. The new
property forces the multiplexer to disconnect child buses in idle state. This is
used, for example, when there are several multiplexers on the same bus and the
devices on the underlying buses might have same I2C addresses.

Signed-off-by: Alexander Sverdlin <alexander.sverdlin@nsn.com>
[wsa: added a newline]
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>

authored by

Alexander Sverdlin and committed by
Wolfram Sang
72f02715 67105c5a

+13 -1
+3
Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt
··· 16 16 Optional Properties: 17 17 18 18 - reset-gpios: Reference to the GPIO connected to the reset input. 19 + - i2c-mux-idle-disconnect: Boolean; if defined, forces mux to disconnect all 20 + children in idle state. This is necessary for example, if there are several 21 + multiplexers on the bus and the devices behind them use same I2C addresses. 19 22 20 23 21 24 Example:
+10 -1
drivers/i2c/muxes/i2c-mux-pca954x.c
··· 41 41 #include <linux/i2c-mux.h> 42 42 #include <linux/i2c/pca954x.h> 43 43 #include <linux/module.h> 44 + #include <linux/of.h> 44 45 #include <linux/pm.h> 45 46 #include <linux/slab.h> 46 47 ··· 187 186 { 188 187 struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent); 189 188 struct pca954x_platform_data *pdata = dev_get_platdata(&client->dev); 189 + struct device_node *of_node = client->dev.of_node; 190 + bool idle_disconnect_dt; 190 191 struct gpio_desc *gpio; 191 192 int num, force, class; 192 193 struct pca954x *data; ··· 220 217 data->type = id->driver_data; 221 218 data->last_chan = 0; /* force the first selection */ 222 219 220 + idle_disconnect_dt = of_node && 221 + of_property_read_bool(of_node, "i2c-mux-idle-disconnect"); 222 + 223 223 /* Now create an adapter for each channel */ 224 224 for (num = 0; num < chips[data->type].nchans; num++) { 225 + bool idle_disconnect_pd = false; 226 + 225 227 force = 0; /* dynamic adap number */ 226 228 class = 0; /* no class by default */ 227 229 if (pdata) { ··· 237 229 } else 238 230 /* discard unconfigured channels */ 239 231 break; 232 + idle_disconnect_pd = pdata->modes[num].deselect_on_exit; 240 233 } 241 234 242 235 data->virt_adaps[num] = 243 236 i2c_add_mux_adapter(adap, &client->dev, client, 244 237 force, num, class, pca954x_select_chan, 245 - (pdata && pdata->modes[num].deselect_on_exit) 238 + (idle_disconnect_pd || idle_disconnect_dt) 246 239 ? pca954x_deselect_mux : NULL); 247 240 248 241 if (data->virt_adaps[num] == NULL) {