Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ASoC: sta32x: Add support for XTI clock

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>

authored by

Daniel Mack and committed by
Mark Brown
fce9ec95 1e3cb6c3

+34
+6
Documentation/devicetree/bindings/sound/st,sta32x.txt
··· 19 19 20 20 Optional properties: 21 21 22 + - clocks, clock-names: Clock specifier for XTI input clock. 23 + If specified, the clock will be enabled when the codec is probed, 24 + and disabled when it is removed. The 'clock-names' must be set to 'xti'. 25 + 22 26 - st,output-conf: number, Selects the output configuration: 23 27 0: 2-channel (full-bridge) power, 2-channel data-out 24 28 1: 2 (half-bridge). 1 (full-bridge) on-board power ··· 83 79 codec: sta32x@38 { 84 80 compatible = "st,sta32x"; 85 81 reg = <0x1c>; 82 + clocks = <&clock>; 83 + clock-names = "xti"; 86 84 reset-gpios = <&gpio1 19 0>; 87 85 power-down-gpios = <&gpio1 16 0>; 88 86 st,output-conf = /bits/ 8 <0x3>; // set output to 2-channel
+28
sound/soc/codecs/sta32x.c
··· 21 21 #include <linux/module.h> 22 22 #include <linux/moduleparam.h> 23 23 #include <linux/init.h> 24 + #include <linux/clk.h> 24 25 #include <linux/delay.h> 25 26 #include <linux/pm.h> 26 27 #include <linux/i2c.h> ··· 143 142 /* codec private data */ 144 143 struct sta32x_priv { 145 144 struct regmap *regmap; 145 + struct clk *xti_clk; 146 146 struct regulator_bulk_data supplies[ARRAY_SIZE(sta32x_supply_names)]; 147 147 struct snd_soc_component *component; 148 148 struct sta32x_platform_data *pdata; ··· 881 879 struct sta32x_priv *sta32x = snd_soc_component_get_drvdata(component); 882 880 struct sta32x_platform_data *pdata = sta32x->pdata; 883 881 int i, ret = 0, thermal = 0; 882 + 883 + sta32x->component = component; 884 + 885 + if (sta32x->xti_clk) { 886 + ret = clk_prepare_enable(sta32x->xti_clk); 887 + if (ret != 0) { 888 + dev_err(component->dev, 889 + "Failed to enable clock: %d\n", ret); 890 + return ret; 891 + } 892 + } 893 + 884 894 ret = regulator_bulk_enable(ARRAY_SIZE(sta32x->supplies), 885 895 sta32x->supplies); 886 896 if (ret != 0) { ··· 995 981 996 982 sta32x_watchdog_stop(sta32x); 997 983 regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies); 984 + 985 + if (sta32x->xti_clk) 986 + clk_disable_unprepare(sta32x->xti_clk); 998 987 } 999 988 1000 989 static const struct snd_soc_component_driver sta32x_component = { ··· 1113 1096 return ret; 1114 1097 } 1115 1098 #endif 1099 + 1100 + /* Clock */ 1101 + sta32x->xti_clk = devm_clk_get(dev, "xti"); 1102 + if (IS_ERR(sta32x->xti_clk)) { 1103 + ret = PTR_ERR(sta32x->xti_clk); 1104 + 1105 + if (ret == -EPROBE_DEFER) 1106 + return ret; 1107 + 1108 + sta32x->xti_clk = NULL; 1109 + } 1116 1110 1117 1111 /* GPIOs */ 1118 1112 sta32x->gpiod_nreset = devm_gpiod_get_optional(dev, "reset",