aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/i2c-mux.c
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2012-10-05 22:23:51 +0200
committerJean Delvare <khali@endymion.delvare>2012-10-05 22:23:51 +0200
commiteee543e8248150e8fb833943c71f40c7b1724600 (patch)
tree56efec8384b2bca4cf926583b52a7cf6136fa76f /drivers/i2c/i2c-mux.c
parentMerge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc (diff)
downloadlinux-dev-eee543e8248150e8fb833943c71f40c7b1724600.tar.xz
linux-dev-eee543e8248150e8fb833943c71f40c7b1724600.zip
i2c-mux: Add support for device auto-detection
Let I2C bus segments behind multiplexers have a class. This allows for device auto-detection on these segments. As long as parent segments don't share the same class, it should be fine. I implemented support in drivers i2c-mux-gpio and i2c-mux-pca954x. I left i2c-mux-pca9541 and i2c-mux-pinctrl alone for the moment as I don't know if this feature makes sense for the use cases of these drivers. Signed-off-by: Jean Delvare <khali@linux-fr.org> Cc: Peter Korsgaard <peter.korsgaard@barco.com> Cc: David Daney <david.daney@cavium.com> Cc: Michael Lawnick <ml.lawnick@gmx.de> Cc: Rodolfo Giometti <giometti@linux.it>
Diffstat (limited to 'drivers/i2c/i2c-mux.c')
-rw-r--r--drivers/i2c/i2c-mux.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/drivers/i2c/i2c-mux.c b/drivers/i2c/i2c-mux.c
index 1038c381aea5..d94e0ce78277 100644
--- a/drivers/i2c/i2c-mux.c
+++ b/drivers/i2c/i2c-mux.c
@@ -88,9 +88,23 @@ static u32 i2c_mux_functionality(struct i2c_adapter *adap)
return parent->algo->functionality(parent);
}
+/* Return all parent classes, merged */
+static unsigned int i2c_mux_parent_classes(struct i2c_adapter *parent)
+{
+ unsigned int class = 0;
+
+ do {
+ class |= parent->class;
+ parent = i2c_parent_is_i2c_adapter(parent);
+ } while (parent);
+
+ return class;
+}
+
struct i2c_adapter *i2c_add_mux_adapter(struct i2c_adapter *parent,
struct device *mux_dev,
void *mux_priv, u32 force_nr, u32 chan_id,
+ unsigned int class,
int (*select) (struct i2c_adapter *,
void *, u32),
int (*deselect) (struct i2c_adapter *,
@@ -127,6 +141,14 @@ struct i2c_adapter *i2c_add_mux_adapter(struct i2c_adapter *parent,
priv->adap.algo_data = priv;
priv->adap.dev.parent = &parent->dev;
+ /* Sanity check on class */
+ if (i2c_mux_parent_classes(parent) & class)
+ dev_err(&parent->dev,
+ "Segment %d behind mux can't share classes with ancestors\n",
+ chan_id);
+ else
+ priv->adap.class = class;
+
/*
* Try to populate the mux adapter's of_node, expands to
* nothing if !CONFIG_OF.