Commit 72f02715 authored by Alexander Sverdlin's avatar Alexander Sverdlin Committed by Wolfram Sang

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: default avatarAlexander Sverdlin <alexander.sverdlin@nsn.com>
[wsa: added a newline]
Signed-off-by: default avatarWolfram Sang <wsa@the-dreams.de>
parent 67105c5a
...@@ -16,6 +16,9 @@ Required Properties: ...@@ -16,6 +16,9 @@ Required Properties:
Optional Properties: Optional Properties:
- reset-gpios: Reference to the GPIO connected to the reset input. - 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: Example:
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#include <linux/i2c-mux.h> #include <linux/i2c-mux.h>
#include <linux/i2c/pca954x.h> #include <linux/i2c/pca954x.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of.h>
#include <linux/pm.h> #include <linux/pm.h>
#include <linux/slab.h> #include <linux/slab.h>
...@@ -186,6 +187,8 @@ static int pca954x_probe(struct i2c_client *client, ...@@ -186,6 +187,8 @@ static int pca954x_probe(struct i2c_client *client,
{ {
struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent); struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent);
struct pca954x_platform_data *pdata = dev_get_platdata(&client->dev); 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; struct gpio_desc *gpio;
int num, force, class; int num, force, class;
struct pca954x *data; struct pca954x *data;
...@@ -217,8 +220,13 @@ static int pca954x_probe(struct i2c_client *client, ...@@ -217,8 +220,13 @@ static int pca954x_probe(struct i2c_client *client,
data->type = id->driver_data; data->type = id->driver_data;
data->last_chan = 0; /* force the first selection */ 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 */ /* Now create an adapter for each channel */
for (num = 0; num < chips[data->type].nchans; num++) { for (num = 0; num < chips[data->type].nchans; num++) {
bool idle_disconnect_pd = false;
force = 0; /* dynamic adap number */ force = 0; /* dynamic adap number */
class = 0; /* no class by default */ class = 0; /* no class by default */
if (pdata) { if (pdata) {
...@@ -229,12 +237,13 @@ static int pca954x_probe(struct i2c_client *client, ...@@ -229,12 +237,13 @@ static int pca954x_probe(struct i2c_client *client,
} else } else
/* discard unconfigured channels */ /* discard unconfigured channels */
break; break;
idle_disconnect_pd = pdata->modes[num].deselect_on_exit;
} }
data->virt_adaps[num] = data->virt_adaps[num] =
i2c_add_mux_adapter(adap, &client->dev, client, i2c_add_mux_adapter(adap, &client->dev, client,
force, num, class, pca954x_select_chan, force, num, class, pca954x_select_chan,
(pdata && pdata->modes[num].deselect_on_exit) (idle_disconnect_pd || idle_disconnect_dt)
? pca954x_deselect_mux : NULL); ? pca954x_deselect_mux : NULL);
if (data->virt_adaps[num] == NULL) { if (data->virt_adaps[num] == NULL) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment