From aa0f18d762215163af12797b74baf014577668c2 Mon Sep 17 00:00:00 2001 From: Steven Eckhoff Date: Wed, 4 Apr 2018 16:49:52 -0500 Subject: [PATCH] ASoC: TSCS42xx: Add CCF support to get sysclk The TSCS42xx relies on set_sysclk to get a unique clock id and rate, which prevents it from being used with the simple-card. Remove set_sysclk callback Add CCF support to get clock id and rate Add clocks and clock-names to device tree binding Signed-off-by: Steven Eckhoff Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/tscs42xx.txt | 6 + sound/soc/codecs/tscs42xx.c | 124 +++++++++++------- sound/soc/codecs/tscs42xx.h | 2 +- 3 files changed, 85 insertions(+), 47 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/tscs42xx.txt b/Documentation/devicetree/bindings/sound/tscs42xx.txt index 2ac2f0996697..7eea32e9d078 100644 --- a/Documentation/devicetree/bindings/sound/tscs42xx.txt +++ b/Documentation/devicetree/bindings/sound/tscs42xx.txt @@ -8,9 +8,15 @@ Required Properties: - reg : <0x71> for analog mic <0x69> for digital mic + - clock-names: Must one of the following "mclk1", "xtal", "mclk2" + + - clocks: phandle of the clock that provides the codec sysclk + Example: wookie: codec@69 { compatible = "tempo,tscs42A2"; reg = <0x69>; + clock-names = "xtal"; + clocks = <&audio_xtal>; }; diff --git a/sound/soc/codecs/tscs42xx.c b/sound/soc/codecs/tscs42xx.c index bf207b0345f1..d18ff17719cc 100644 --- a/sound/soc/codecs/tscs42xx.c +++ b/sound/soc/codecs/tscs42xx.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -40,6 +41,9 @@ struct tscs42xx { struct mutex pll_lock; struct regmap *regmap; + + struct clk *sysclk; + int sysclk_src_id; }; struct coeff_ram_ctl { @@ -1251,56 +1255,11 @@ static int tscs42xx_set_dai_bclk_ratio(struct snd_soc_dai *codec_dai, return 0; } -static int tscs42xx_set_dai_sysclk(struct snd_soc_dai *codec_dai, - int clk_id, unsigned int freq, int dir) -{ - struct snd_soc_component *component = codec_dai->component; - int ret; - - switch (clk_id) { - case TSCS42XX_PLL_SRC_XTAL: - case TSCS42XX_PLL_SRC_MCLK1: - ret = snd_soc_component_write(component, R_PLLREFSEL, - RV_PLLREFSEL_PLL1_REF_SEL_XTAL_MCLK1 | - RV_PLLREFSEL_PLL2_REF_SEL_XTAL_MCLK1); - if (ret < 0) { - dev_err(component->dev, - "Failed to set pll reference input (%d)\n", - ret); - return ret; - } - break; - case TSCS42XX_PLL_SRC_MCLK2: - ret = snd_soc_component_write(component, R_PLLREFSEL, - RV_PLLREFSEL_PLL1_REF_SEL_MCLK2 | - RV_PLLREFSEL_PLL2_REF_SEL_MCLK2); - if (ret < 0) { - dev_err(component->dev, - "Failed to set PLL reference (%d)\n", ret); - return ret; - } - break; - default: - dev_err(component->dev, "pll src is unsupported\n"); - return -EINVAL; - } - - ret = set_pll_ctl_from_input_freq(component, freq); - if (ret < 0) { - dev_err(component->dev, - "Failed to setup PLL input freq (%d)\n", ret); - return ret; - } - - return 0; -} - static const struct snd_soc_dai_ops tscs42xx_dai_ops = { .hw_params = tscs42xx_hw_params, .mute_stream = tscs42xx_mute_stream, .set_fmt = tscs42xx_set_dai_fmt, .set_bclk_ratio = tscs42xx_set_dai_bclk_ratio, - .set_sysclk = tscs42xx_set_dai_sysclk, }; static int part_is_valid(struct tscs42xx *tscs42xx) @@ -1329,7 +1288,58 @@ static int part_is_valid(struct tscs42xx *tscs42xx) }; } +static int set_sysclk(struct snd_soc_component *component) +{ + struct tscs42xx *tscs42xx = snd_soc_component_get_drvdata(component); + unsigned long freq; + int ret; + + switch (tscs42xx->sysclk_src_id) { + case TSCS42XX_PLL_SRC_XTAL: + case TSCS42XX_PLL_SRC_MCLK1: + ret = snd_soc_component_write(component, R_PLLREFSEL, + RV_PLLREFSEL_PLL1_REF_SEL_XTAL_MCLK1 | + RV_PLLREFSEL_PLL2_REF_SEL_XTAL_MCLK1); + if (ret < 0) { + dev_err(component->dev, + "Failed to set pll reference input (%d)\n", + ret); + return ret; + } + break; + case TSCS42XX_PLL_SRC_MCLK2: + ret = snd_soc_component_write(component, R_PLLREFSEL, + RV_PLLREFSEL_PLL1_REF_SEL_MCLK2 | + RV_PLLREFSEL_PLL2_REF_SEL_MCLK2); + if (ret < 0) { + dev_err(component->dev, + "Failed to set PLL reference (%d)\n", ret); + return ret; + } + break; + default: + dev_err(component->dev, "pll src is unsupported\n"); + return -EINVAL; + } + + freq = clk_get_rate(tscs42xx->sysclk); + ret = set_pll_ctl_from_input_freq(component, freq); + if (ret < 0) { + dev_err(component->dev, + "Failed to setup PLL input freq (%d)\n", ret); + return ret; + } + + return 0; +} + +static int tscs42xx_probe(struct snd_soc_component *component) +{ + return set_sysclk(component); +} + static const struct snd_soc_component_driver soc_codec_dev_tscs42xx = { + .probe = tscs42xx_probe, .dapm_widgets = tscs42xx_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(tscs42xx_dapm_widgets), .dapm_routes = tscs42xx_intercon, @@ -1387,11 +1397,15 @@ static const struct reg_sequence tscs42xx_patch[] = { { R_AIC2, RV_AIC2_BLRCM_DAC_BCLK_LRCLK_SHARED }, }; +static char const * const src_names[TSCS42XX_PLL_SRC_CNT] = { + "xtal", "mclk1", "mclk2"}; + static int tscs42xx_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct tscs42xx *tscs42xx; - int ret = 0; + int src; + int ret; tscs42xx = devm_kzalloc(&i2c->dev, sizeof(*tscs42xx), GFP_KERNEL); if (!tscs42xx) { @@ -1402,6 +1416,24 @@ static int tscs42xx_i2c_probe(struct i2c_client *i2c, } i2c_set_clientdata(i2c, tscs42xx); + for (src = TSCS42XX_PLL_SRC_XTAL; src < TSCS42XX_PLL_SRC_CNT; src++) { + tscs42xx->sysclk = devm_clk_get(&i2c->dev, src_names[src]); + if (!IS_ERR(tscs42xx->sysclk)) { + break; + } else if (PTR_ERR(tscs42xx->sysclk) != -ENOENT) { + ret = PTR_ERR(tscs42xx->sysclk); + dev_err(&i2c->dev, "Failed to get sysclk (%d)\n", ret); + return ret; + } + } + if (src == TSCS42XX_PLL_SRC_CNT) { + ret = -EINVAL; + dev_err(&i2c->dev, "Failed to get a valid clock name (%d)\n", + ret); + return ret; + } + tscs42xx->sysclk_src_id = src; + tscs42xx->regmap = devm_regmap_init_i2c(i2c, &tscs42xx_regmap); if (IS_ERR(tscs42xx->regmap)) { ret = PTR_ERR(tscs42xx->regmap); diff --git a/sound/soc/codecs/tscs42xx.h b/sound/soc/codecs/tscs42xx.h index d4a30bcbf64b..814c8f3c4a68 100644 --- a/sound/soc/codecs/tscs42xx.h +++ b/sound/soc/codecs/tscs42xx.h @@ -7,10 +7,10 @@ #define __WOOKIE_H__ enum { - TSCS42XX_PLL_SRC_NONE, TSCS42XX_PLL_SRC_XTAL, TSCS42XX_PLL_SRC_MCLK1, TSCS42XX_PLL_SRC_MCLK2, + TSCS42XX_PLL_SRC_CNT, }; #define R_HPVOLL 0x0