i2c: omap: Add support for setting mux
authorJayesh Choudhary <j-choudhary@ti.com>
Tue, 18 Mar 2025 10:36:22 +0000 (16:06 +0530)
committerAndi Shyti <andi.shyti@kernel.org>
Fri, 21 Mar 2025 00:31:02 +0000 (01:31 +0100)
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>
drivers/i2c/busses/Kconfig
drivers/i2c/busses/i2c-omap.c

index fc438f4457713d5559d163840a7b11e8cdbb8f58..0648e58b083ec5b5bffffbdf30ac2718e3ac1e85 100644 (file)
@@ -940,6 +940,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 f18c3e74b07626ade89332f954f2ef5d15d58deb..16afb9ca19bba9a0878b4b68619399db1a2642a1 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/slab.h>
 #include <linux/platform_data/i2c-omap.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[] = {
@@ -1452,6 +1454,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);
 
@@ -1511,6 +1530,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");