]> 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:56:37 +0000 (08:56 +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 2254abda5c46c9e19eb6ae22c920f6f982be5116..0e679cc5014882a323bb7a2d4204b579d737102d 100644 (file)
@@ -937,6 +937,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 8c9cf08ad45e2257b064a697c077f5a086952477..488ee9de641085da94482989dc6f32e708c4d9fa 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");