]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
iio: adc: ad7124: add clock output support
authorDavid Lechner <dlechner@baylibre.com>
Thu, 28 Aug 2025 21:54:55 +0000 (16:54 -0500)
committerJonathan Cameron <Jonathan.Cameron@huawei.com>
Sat, 30 Aug 2025 19:46:56 +0000 (20:46 +0100)
Add support for the AD7124's internal clock output. If the #clock-cells
property is present, turn on the internal clock output during probe.

If both the clocks and #clock-names properties are present (not allowed
by devicetree bindings), assume that an external clock is being used so
that we don't accidentally have two outputs fighting each other.

Signed-off-by: David Lechner <dlechner@baylibre.com>
Link: https://patch.msgid.link/20250828-iio-adc-ad7124-proper-clock-support-v3-4-0b317b4605e5@baylibre.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
drivers/iio/adc/ad7124.c

index 1a9a8d6f1943398fa6cd257527aed99559d3e8d0..d5bb0faf9111ef72fd452e02a72a97dad35f762c 100644 (file)
@@ -6,7 +6,9 @@
  */
 #include <linux/bitfield.h>
 #include <linux/bitops.h>
+#include <linux/cleanup.h>
 #include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/err.h>
@@ -18,6 +20,7 @@
 #include <linux/property.h>
 #include <linux/regulator/consumer.h>
 #include <linux/spi/spi.h>
+#include <linux/sprintf.h>
 #include <linux/units.h>
 
 #include <linux/iio/iio.h>
@@ -1189,6 +1192,36 @@ static int ad7124_setup(struct ad7124_state *st)
 
                clk_sel = AD7124_ADC_CONTROL_CLK_SEL_INT;
                st->clk_hz = AD7124_INT_CLK_HZ;
+       } else if (!device_property_present(dev, "clocks") &&
+                  device_property_present(dev, "#clock-cells")) {
+#ifdef CONFIG_COMMON_CLK
+               struct clk_hw *clk_hw;
+
+               const char *name __free(kfree) = kasprintf(GFP_KERNEL, "%pfwP-clk",
+                                                          dev_fwnode(dev));
+               if (!name)
+                       return -ENOMEM;
+
+               clk_hw = devm_clk_hw_register_fixed_rate(dev, name, NULL, 0,
+                                                        AD7124_INT_CLK_HZ);
+               if (IS_ERR(clk_hw))
+                       return dev_err_probe(dev, PTR_ERR(clk_hw),
+                                            "Failed to register clock provider\n");
+
+               ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get,
+                                                 clk_hw);
+               if (ret)
+                       return dev_err_probe(dev, ret,
+                                            "Failed to add clock provider\n");
+#endif
+
+               /*
+                * Treat the clock as always on. This way we don't have to deal
+                * with someone trying to enable/disable the clock while we are
+                * reading samples.
+                */
+               clk_sel = AD7124_ADC_CONTROL_CLK_SEL_INT_OUT;
+               st->clk_hz = AD7124_INT_CLK_HZ;
        } else {
                struct clk *clk;