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>
This commit is contained in:
Daniel Mack 2018-10-17 13:37:03 +02:00 committed by Mark Brown
parent 1e3cb6c321
commit fce9ec954a
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0
2 changed files with 34 additions and 0 deletions

View 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

View 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);