diff options
Diffstat (limited to 'target/linux/brcm2708/patches-4.19/950-0400-ASoC-tlv320aic32x4-Model-CODEC_CLKIN-in-CCF.patch')
-rw-r--r-- | target/linux/brcm2708/patches-4.19/950-0400-ASoC-tlv320aic32x4-Model-CODEC_CLKIN-in-CCF.patch | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/target/linux/brcm2708/patches-4.19/950-0400-ASoC-tlv320aic32x4-Model-CODEC_CLKIN-in-CCF.patch b/target/linux/brcm2708/patches-4.19/950-0400-ASoC-tlv320aic32x4-Model-CODEC_CLKIN-in-CCF.patch new file mode 100644 index 0000000000..87bfdf1f39 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0400-ASoC-tlv320aic32x4-Model-CODEC_CLKIN-in-CCF.patch @@ -0,0 +1,120 @@ +From cb191833ad3ce88d4cf8b669b0d68a2b8dafae5f Mon Sep 17 00:00:00 2001 +From: Annaliese McDermond <nh6z@nh6z.net> +Date: Thu, 21 Mar 2019 17:58:46 -0700 +Subject: [PATCH 400/782] ASoC: tlv320aic32x4: Model CODEC_CLKIN in CCF + +commit fd2df3aeafa4b4cc468d58e147e0822967034b71 upstream. + +Model and manage codec clock input as a component in the Core +Clock Framework. This should allow us to do some more complex +clock management and power control. Also, some of the +on-board chip clocks can be exposed to the outside, and this +change will make those clocks easier to consume by other +parts of the kernel. + +Signed-off-by: Annaliese McDermond <nh6z@nh6z.net> +Signed-off-by: Mark Brown <broonie@kernel.org> +--- + sound/soc/codecs/tlv320aic32x4-clk.c | 34 ++++++++++++++++++++++++++++ + sound/soc/codecs/tlv320aic32x4.c | 18 +++++++++++---- + 2 files changed, 47 insertions(+), 5 deletions(-) + +--- a/sound/soc/codecs/tlv320aic32x4-clk.c ++++ b/sound/soc/codecs/tlv320aic32x4-clk.c +@@ -265,6 +265,30 @@ static const struct clk_ops aic32x4_pll_ + .get_parent = clk_aic32x4_pll_get_parent, + }; + ++static int clk_aic32x4_codec_clkin_set_parent(struct clk_hw *hw, u8 index) ++{ ++ struct clk_aic32x4 *mux = to_clk_aic32x4(hw); ++ ++ return regmap_update_bits(mux->regmap, ++ AIC32X4_CLKMUX, ++ AIC32X4_CODEC_CLKIN_MASK, index << AIC32X4_CODEC_CLKIN_SHIFT); ++} ++ ++static u8 clk_aic32x4_codec_clkin_get_parent(struct clk_hw *hw) ++{ ++ struct clk_aic32x4 *mux = to_clk_aic32x4(hw); ++ unsigned int val; ++ ++ regmap_read(mux->regmap, AIC32X4_CLKMUX, &val); ++ ++ return (val & AIC32X4_CODEC_CLKIN_MASK) >> AIC32X4_CODEC_CLKIN_SHIFT; ++} ++ ++static const struct clk_ops aic32x4_codec_clkin_ops = { ++ .set_parent = clk_aic32x4_codec_clkin_set_parent, ++ .get_parent = clk_aic32x4_codec_clkin_get_parent, ++}; ++ + static struct aic32x4_clkdesc aic32x4_clkdesc_array[] = { + { + .name = "pll", +@@ -274,6 +298,14 @@ static struct aic32x4_clkdesc aic32x4_cl + .ops = &aic32x4_pll_ops, + .reg = 0, + }, ++ { ++ .name = "codec_clkin", ++ .parent_names = ++ (const char *[]) { "mclk", "bclk", "gpio", "pll" }, ++ .num_parents = 4, ++ .ops = &aic32x4_codec_clkin_ops, ++ .reg = 0, ++ }, + }; + + static struct clk *aic32x4_register_clk(struct device *dev, +@@ -314,6 +346,8 @@ int aic32x4_register_clocks(struct devic + */ + aic32x4_clkdesc_array[0].parent_names = + (const char* []) { mclk_name, "bclk", "gpio", "din" }; ++ aic32x4_clkdesc_array[1].parent_names = ++ (const char *[]) { mclk_name, "bclk", "gpio", "pll" }; + + for (i = 0; i < ARRAY_SIZE(aic32x4_clkdesc_array); ++i) + aic32x4_register_clk(dev, &aic32x4_clkdesc_array[i]); +--- a/sound/soc/codecs/tlv320aic32x4.c ++++ b/sound/soc/codecs/tlv320aic32x4.c +@@ -737,12 +737,9 @@ static int aic32x4_setup_clocks(struct s + + aic32x4_set_processing_blocks(component, aic32x4_divs[i].r_block, aic32x4_divs[i].p_block); + +- /* PLL as CODEC_CLKIN */ +- snd_soc_component_update_bits(component, AIC32X4_CLKMUX, +- AIC32X4_CODEC_CLKIN_MASK, +- AIC32X4_CODEC_CLKIN_PLL << AIC32X4_CODEC_CLKIN_SHIFT); + /* DAC_MOD_CLK as BDIV_CLKIN */ +- snd_soc_component_update_bits(component, AIC32X4_IFACE3, AIC32X4_BDIVCLK_MASK, ++ snd_soc_component_update_bits(component, AIC32X4_IFACE3, ++ AIC32X4_BDIVCLK_MASK, + AIC32X4_DACMOD2BCLK << AIC32X4_BDIVCLK_SHIFT); + + /* NDAC divider value */ +@@ -989,6 +986,15 @@ static int aic32x4_component_probe(struc + { + struct aic32x4_priv *aic32x4 = snd_soc_component_get_drvdata(component); + u32 tmp_reg; ++ int ret; ++ ++ struct clk_bulk_data clocks[] = { ++ { .id = "codec_clkin" }, ++ }; ++ ++ ret = devm_clk_bulk_get(component->dev, ARRAY_SIZE(clocks), clocks); ++ if (ret) ++ return ret; + + if (gpio_is_valid(aic32x4->rstn_gpio)) { + ndelay(10); +@@ -1000,6 +1006,8 @@ static int aic32x4_component_probe(struc + if (aic32x4->setup) + aic32x4_setup_gpios(component); + ++ clk_set_parent(clocks[0].clk, clocks[1].clk); ++ + /* Power platform configuration */ + if (aic32x4->power_cfg & AIC32X4_PWR_MICBIAS_2075_LDOIN) { + snd_soc_component_write(component, AIC32X4_MICBIAS, |