ASoC: sta32x: Add support for XTI clock
authorDaniel Mack <daniel@zonque.org>
Wed, 17 Oct 2018 11:37:03 +0000 (13:37 +0200)
committerMark Brown <broonie@kernel.org>
Wed, 17 Oct 2018 19:01:25 +0000 (20:01 +0100)
The STA32x chips feature an XTI clock input that needs to be stable before
the reset signal is released. Therefore, the chip driver needs to get a
handle to the clock. Instead of relying on other parts of the system to
enable the clock, let the codec driver grab a handle itself.

In order to keep existing boards working, clock support is made optional.

Signed-off-by: Daniel Mack <daniel@zonque.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
Documentation/devicetree/bindings/sound/st,sta32x.txt
sound/soc/codecs/sta32x.c

index ff4a685a43036ee12675b9962987ec5d34d0dc8f..52265fb757c58e84dd2553c1024b9775946888f9 100644 (file)
@@ -19,6 +19,10 @@ Required properties:
 
 Optional properties:
 
+  - clocks, clock-names: Clock specifier for XTI input clock.
+       If specified, the clock will be enabled when the codec is probed,
+       and disabled when it is removed. The 'clock-names' must be set to 'xti'.
+
   -  st,output-conf: number, Selects the output configuration:
        0: 2-channel (full-bridge) power, 2-channel data-out
        1: 2 (half-bridge). 1 (full-bridge) on-board power
@@ -79,6 +83,8 @@ Example:
 codec: sta32x@38 {
        compatible = "st,sta32x";
        reg = <0x1c>;
+       clocks = <&clock>;
+       clock-names = "xti";
        reset-gpios = <&gpio1 19 0>;
        power-down-gpios = <&gpio1 16 0>;
        st,output-conf = /bits/ 8  <0x3>;       // set output to 2-channel
index 22de1593443cc48c721acd8b34e2bccc9adfe3b3..f753d2db0a5a75e023d113106ed17657654ba556 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/init.h>
+#include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
@@ -142,6 +143,7 @@ static const char *sta32x_supply_names[] = {
 /* codec private data */
 struct sta32x_priv {
        struct regmap *regmap;
+       struct clk *xti_clk;
        struct regulator_bulk_data supplies[ARRAY_SIZE(sta32x_supply_names)];
        struct snd_soc_component *component;
        struct sta32x_platform_data *pdata;
@@ -879,6 +881,18 @@ static int sta32x_probe(struct snd_soc_component *component)
        struct sta32x_priv *sta32x = snd_soc_component_get_drvdata(component);
        struct sta32x_platform_data *pdata = sta32x->pdata;
        int i, ret = 0, thermal = 0;
+
+       sta32x->component = component;
+
+       if (sta32x->xti_clk) {
+               ret = clk_prepare_enable(sta32x->xti_clk);
+               if (ret != 0) {
+                       dev_err(component->dev,
+                               "Failed to enable clock: %d\n", ret);
+                       return ret;
+               }
+       }
+
        ret = regulator_bulk_enable(ARRAY_SIZE(sta32x->supplies),
                                    sta32x->supplies);
        if (ret != 0) {
@@ -981,6 +995,9 @@ static void sta32x_remove(struct snd_soc_component *component)
 
        sta32x_watchdog_stop(sta32x);
        regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
+
+       if (sta32x->xti_clk)
+               clk_disable_unprepare(sta32x->xti_clk);
 }
 
 static const struct snd_soc_component_driver sta32x_component = {
@@ -1097,6 +1114,17 @@ static int sta32x_i2c_probe(struct i2c_client *i2c,
        }
 #endif
 
+       /* Clock */
+       sta32x->xti_clk = devm_clk_get(dev, "xti");
+       if (IS_ERR(sta32x->xti_clk)) {
+               ret = PTR_ERR(sta32x->xti_clk);
+
+               if (ret == -EPROBE_DEFER)
+                       return ret;
+
+               sta32x->xti_clk = NULL;
+       }
+
        /* GPIOs */
        sta32x->gpiod_nreset = devm_gpiod_get_optional(dev, "reset",
                                                       GPIOD_OUT_LOW);