]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
i2c: omap: Add support for setting mux
authorJayesh Choudhary <j-choudhary@ti.com>
Tue, 18 Mar 2025 10:36:22 +0000 (16:06 +0530)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 24 Jul 2025 06:53:21 +0000 (08:53 +0200)
commit b6ef830c60b6f4adfb72d0780b4363df3a1feb9c upstream.

Some SoCs require muxes in the routing for SDA and SCL lines.
Therefore, add support for setting the mux by reading the mux-states
property from the dt-node.

Signed-off-by: Jayesh Choudhary <j-choudhary@ti.com>
Link: https://lore.kernel.org/r/20250318103622.29979-3-j-choudhary@ti.com
Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
Stable-dep-of: a9503a2ecd95 ("i2c: omap: Handle omap_i2c_init() errors in omap_i2c_probe()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/i2c/busses/Kconfig
drivers/i2c/busses/i2c-omap.c

index 982007a112c2a082d1d201eb9116684623f7c3a3..8d4270664ebd1142bcb84d5b3f7f457458203149 100644 (file)
@@ -899,6 +899,7 @@ config I2C_OMAP
        tristate "OMAP I2C adapter"
        depends on ARCH_OMAP || ARCH_K3 || COMPILE_TEST
        default MACH_OMAP_OSK
+       select MULTIPLEXER
        help
          If you say yes to this option, support will be included for the
          I2C interface on the Texas Instruments OMAP1/2 family of processors.
index 22975bfd6b252bff8efa4fa597d3f01b4190608b..ffc116e76ba1867d0337fe9ae561b7561b388655 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/platform_device.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/mux/consumer.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/slab.h>
@@ -211,6 +212,7 @@ struct omap_i2c_dev {
        u16                     syscstate;
        u16                     westate;
        u16                     errata;
+       struct mux_state        *mux_state;
 };
 
 static const u8 reg_map_ip_v1[] = {
@@ -1455,6 +1457,23 @@ omap_i2c_probe(struct platform_device *pdev)
                                       (1000 * omap->speed / 8);
        }
 
+       if (of_property_read_bool(node, "mux-states")) {
+               struct mux_state *mux_state;
+
+               mux_state = devm_mux_state_get(&pdev->dev, NULL);
+               if (IS_ERR(mux_state)) {
+                       r = PTR_ERR(mux_state);
+                       dev_dbg(&pdev->dev, "failed to get I2C mux: %d\n", r);
+                       goto err_disable_pm;
+               }
+               omap->mux_state = mux_state;
+               r = mux_state_select(omap->mux_state);
+               if (r) {
+                       dev_err(&pdev->dev, "failed to select I2C mux: %d\n", r);
+                       goto err_disable_pm;
+               }
+       }
+
        /* reset ASAP, clearing any IRQs */
        omap_i2c_init(omap);
 
@@ -1514,6 +1533,9 @@ static void omap_i2c_remove(struct platform_device *pdev)
 
        i2c_del_adapter(&omap->adapter);
 
+       if (omap->mux_state)
+               mux_state_deselect(omap->mux_state);
+
        ret = pm_runtime_get_sync(&pdev->dev);
        if (ret < 0)
                dev_err(omap->dev, "Failed to resume hardware, skip disable\n");