]> git.karo-electronics.de Git - linux-beck.git/commitdiff
of: i2c: Add i2c-mux-idle-disconnect DT property to PCA954x mux driver
authorAlexander Sverdlin <alexander.sverdlin@nsn.com>
Fri, 23 Jan 2015 15:41:29 +0000 (16:41 +0100)
committerWolfram Sang <wsa@the-dreams.de>
Fri, 23 Jan 2015 16:12:56 +0000 (17:12 +0100)
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>
Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt
drivers/i2c/muxes/i2c-mux-pca954x.c

index 34a3fb6f8488b26a9c5def9866898d807ee7df55..cf53d5fba20a0934c631b8320e538cbc5440e155 100644 (file)
@@ -16,6 +16,9 @@ Required Properties:
 Optional Properties:
 
   - reset-gpios: Reference to the GPIO connected to the reset input.
+  - i2c-mux-idle-disconnect: Boolean; if defined, forces mux to disconnect all
+    children in idle state. This is necessary for example, if there are several
+    multiplexers on the bus and the devices behind them use same I2C addresses.
 
 
 Example:
index ec11b404b433737657957ef9dd0e559a955b45aa..3d8f4fe2e47e52eefff7da7967fe41bf0fafe801 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/i2c-mux.h>
 #include <linux/i2c/pca954x.h>
 #include <linux/module.h>
+#include <linux/of.h>
 #include <linux/pm.h>
 #include <linux/slab.h>
 
@@ -186,6 +187,8 @@ static int pca954x_probe(struct i2c_client *client,
 {
        struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent);
        struct pca954x_platform_data *pdata = dev_get_platdata(&client->dev);
+       struct device_node *of_node = client->dev.of_node;
+       bool idle_disconnect_dt;
        struct gpio_desc *gpio;
        int num, force, class;
        struct pca954x *data;
@@ -217,8 +220,13 @@ static int pca954x_probe(struct i2c_client *client,
        data->type = id->driver_data;
        data->last_chan = 0;               /* force the first selection */
 
+       idle_disconnect_dt = of_node &&
+               of_property_read_bool(of_node, "i2c-mux-idle-disconnect");
+
        /* Now create an adapter for each channel */
        for (num = 0; num < chips[data->type].nchans; num++) {
+               bool idle_disconnect_pd = false;
+
                force = 0;                        /* dynamic adap number */
                class = 0;                        /* no class by default */
                if (pdata) {
@@ -229,12 +237,13 @@ static int pca954x_probe(struct i2c_client *client,
                        } else
                                /* discard unconfigured channels */
                                break;
+                       idle_disconnect_pd = pdata->modes[num].deselect_on_exit;
                }
 
                data->virt_adaps[num] =
                        i2c_add_mux_adapter(adap, &client->dev, client,
                                force, num, class, pca954x_select_chan,
-                               (pdata && pdata->modes[num].deselect_on_exit)
+                               (idle_disconnect_pd || idle_disconnect_dt)
                                        ? pca954x_deselect_mux : NULL);
 
                if (data->virt_adaps[num] == NULL) {