linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Samuel Holland <samuel@sholland.org>
To: "Mark Brown" <broonie@kernel.org>,
	"Liam Girdwood" <lgirdwood@gmail.com>,
	"Rob Herring" <robh+dt@kernel.org>,
	"Mark Rutland" <mark.rutland@arm.com>,
	"Maxime Ripard" <mripard@kernel.org>,
	"Chen-Yu Tsai" <wens@csie.org>,
	"Vasily Khoruzhick" <anarsoul@gmail.com>,
	"Mylène Josserand" <mylene.josserand@free-electrons.com>,
	"Jaroslav Kysela" <perex@perex.cz>,
	"Takashi Iwai" <tiwai@suse.com>
Cc: alsa-devel@alsa-project.org, devicetree@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org,
	Samuel Holland <samuel@sholland.org>
Subject: [RFC PATCH 21/34] ASoC: sun8i-codec: Clean up module/clock hierarchy
Date: Mon, 17 Feb 2020 00:42:37 -0600	[thread overview]
Message-ID: <20200217064250.15516-22-samuel@sholland.org> (raw)
In-Reply-To: <20200217064250.15516-1-samuel@sholland.org>

The clock hieriarchy in the codec is:

       MCLK/PLL      MCLK/PLL
          |              |
       AIF1CLK        AIF2CLK
         |    \      /    |
         |     SYSCLK     |
         |       ||       |
         |   MODCLK ***   |
         |       ||       |
         |    RST ****    |
         |   /  /  \  \   |
         AIF1 ADC  DAC AIF2

Currently, this driver makes some design decisions:
 - AIF1CLK/AIF2CLK should always have the PLL as their parent. MCLK may
   not be running, and it has the same PLL as its parent anyway.
 - SYSCLK should always have AIF1CLK as its parent. There is no easy way
   for DAPM to automatically switch clock parents based on which AIFs
   are in use, and AIF1 is most likely to be used. Even in the case
   where only AIF2 is used, the extra power consumption by also running
   AIF1CLK should be minimal.

This commit updates the driver to match the hardware clock hierarchy:
 - Since the clock parent decisions are static, they are configured once
   in the component's probe function. They do not need DAPM widgets.
 - ADC/DAC supplies are moved immediately after the widgets they supply.
 - Module resets are moved before module clocks to maintain topological
   ordering (and they are sorted by bit order within the register).
 - AIF1 module is supplied by both SYSCLK (via MODCLK AIF1) and AIF1CLK.
 - ADC/DAC modules are supplied by SYSCLK only, not MODCLK AIF1.
 - SYSCLK is supplied by AIF1CLK.

Signed-off-by: Samuel Holland <samuel@sholland.org>
---
 sound/soc/sunxi/sun8i-codec.c | 114 ++++++++++++++++++++--------------
 1 file changed, 68 insertions(+), 46 deletions(-)

diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c
index b915e62fa005..0561d8d2e941 100644
--- a/sound/soc/sunxi/sun8i-codec.c
+++ b/sound/soc/sunxi/sun8i-codec.c
@@ -24,10 +24,11 @@
 
 #define SUN8I_SYSCLK_CTL				0x00c
 #define SUN8I_SYSCLK_CTL_AIF1CLK_ENA			11
-#define SUN8I_SYSCLK_CTL_AIF1CLK_SRC_PLL		9
-#define SUN8I_SYSCLK_CTL_AIF1CLK_SRC			8
+#define SUN8I_SYSCLK_CTL_AIF1CLK_SRC_PLL		(0x3 << 8)
 #define SUN8I_SYSCLK_CTL_SYSCLK_ENA			3
 #define SUN8I_SYSCLK_CTL_SYSCLK_SRC			0
+#define SUN8I_SYSCLK_CTL_SYSCLK_SRC_AIF1CLK		(0x0 << 0)
+#define SUN8I_SYSCLK_CTL_SYSCLK_SRC_AIF2CLK		(0x1 << 0)
 #define SUN8I_MOD_CLK_ENA				0x010
 #define SUN8I_MOD_CLK_ENA_AIF1				15
 #define SUN8I_MOD_CLK_ENA_ADC				3
@@ -78,6 +79,7 @@
 #define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF2DACR		9
 #define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_ADCR		8
 
+#define SUN8I_SYSCLK_CTL_AIF1CLK_SRC_MASK	GENMASK(9, 8)
 #define SUN8I_SYS_SR_CTRL_AIF1_FS_MASK		GENMASK(15, 12)
 #define SUN8I_SYS_SR_CTRL_AIF2_FS_MASK		GENMASK(11, 8)
 #define SUN8I_AIF1CLK_CTRL_AIF1_CLK_INV_MASK	GENMASK(14, 13)
@@ -418,12 +420,6 @@ static const struct snd_kcontrol_new sun8i_input_mixer_controls[] = {
 };
 
 static const struct snd_soc_dapm_widget sun8i_codec_dapm_widgets[] = {
-	/* Digital parts of the DACs and ADC */
-	SND_SOC_DAPM_SUPPLY("DAC", SUN8I_DAC_DIG_CTRL, SUN8I_DAC_DIG_CTRL_ENDA,
-			    0, NULL, 0),
-	SND_SOC_DAPM_SUPPLY("ADC", SUN8I_ADC_DIG_CTRL, SUN8I_ADC_DIG_CTRL_ENAD,
-			    0, NULL, 0),
-
 	/* Analog DAC AIF */
 	SND_SOC_DAPM_AIF_IN("AIF1 Slot 0 Left", "Playback", 0,
 			    SUN8I_AIF1_DACDAT_CTRL,
@@ -444,6 +440,9 @@ static const struct snd_soc_dapm_widget sun8i_codec_dapm_widgets[] = {
 	SND_SOC_DAPM_PGA("DAC Left", SND_SOC_NOPM, 0, 0, NULL, 0),
 	SND_SOC_DAPM_PGA("DAC Right", SND_SOC_NOPM, 0, 0, NULL, 0),
 
+	SND_SOC_DAPM_SUPPLY("DAC", SUN8I_DAC_DIG_CTRL,
+			    SUN8I_DAC_DIG_CTRL_ENDA, 0, NULL, 0),
+
 	/* DAC and ADC Mixers */
 	SOC_MIXER_ARRAY("Left Digital DAC Mixer", SND_SOC_NOPM, 0, 0,
 			sun8i_dac_mixer_controls),
@@ -458,60 +457,43 @@ static const struct snd_soc_dapm_widget sun8i_codec_dapm_widgets[] = {
 	SND_SOC_DAPM_PGA("ADC Left", SND_SOC_NOPM, 0, 0, NULL, 0),
 	SND_SOC_DAPM_PGA("ADC Right", SND_SOC_NOPM, 0, 0, NULL, 0),
 
-	/* Clocks */
+	SND_SOC_DAPM_SUPPLY("ADC", SUN8I_ADC_DIG_CTRL,
+			    SUN8I_ADC_DIG_CTRL_ENAD, 0, NULL, 0),
+
+	/* Module Resets */
+	SND_SOC_DAPM_SUPPLY("RST AIF1", SUN8I_MOD_RST_CTL,
+			    SUN8I_MOD_RST_CTL_AIF1, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("RST ADC", SUN8I_MOD_RST_CTL,
+			    SUN8I_MOD_RST_CTL_ADC, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("RST DAC", SUN8I_MOD_RST_CTL,
+			    SUN8I_MOD_RST_CTL_DAC, 0, NULL, 0),
+
+	/* Module Clocks */
 	SND_SOC_DAPM_SUPPLY("MODCLK AIF1", SUN8I_MOD_CLK_ENA,
 			    SUN8I_MOD_CLK_ENA_AIF1, 0, NULL, 0),
-	SND_SOC_DAPM_SUPPLY("MODCLK DAC", SUN8I_MOD_CLK_ENA,
-			    SUN8I_MOD_CLK_ENA_DAC, 0, NULL, 0),
 	SND_SOC_DAPM_SUPPLY("MODCLK ADC", SUN8I_MOD_CLK_ENA,
 			    SUN8I_MOD_CLK_ENA_ADC, 0, NULL, 0),
-	SND_SOC_DAPM_SUPPLY("AIF1", SUN8I_SYSCLK_CTL,
+	SND_SOC_DAPM_SUPPLY("MODCLK DAC", SUN8I_MOD_CLK_ENA,
+			    SUN8I_MOD_CLK_ENA_DAC, 0, NULL, 0),
+
+	/* Clock Supplies */
+	SND_SOC_DAPM_SUPPLY("AIF1CLK", SUN8I_SYSCLK_CTL,
 			    SUN8I_SYSCLK_CTL_AIF1CLK_ENA, 0, NULL, 0),
 	SND_SOC_DAPM_SUPPLY("SYSCLK", SUN8I_SYSCLK_CTL,
 			    SUN8I_SYSCLK_CTL_SYSCLK_ENA, 0, NULL, 0),
-
-	SND_SOC_DAPM_SUPPLY("AIF1 PLL", SUN8I_SYSCLK_CTL,
-			    SUN8I_SYSCLK_CTL_AIF1CLK_SRC_PLL, 0, NULL, 0),
-	/* Inversion as 0=AIF1, 1=AIF2 */
-	SND_SOC_DAPM_SUPPLY("SYSCLK AIF1", SUN8I_SYSCLK_CTL,
-			    SUN8I_SYSCLK_CTL_SYSCLK_SRC, 1, NULL, 0),
-
-	/* Module reset */
-	SND_SOC_DAPM_SUPPLY("RST AIF1", SUN8I_MOD_RST_CTL,
-			    SUN8I_MOD_RST_CTL_AIF1, 0, NULL, 0),
-	SND_SOC_DAPM_SUPPLY("RST DAC", SUN8I_MOD_RST_CTL,
-			    SUN8I_MOD_RST_CTL_DAC, 0, NULL, 0),
-	SND_SOC_DAPM_SUPPLY("RST ADC", SUN8I_MOD_RST_CTL,
-			    SUN8I_MOD_RST_CTL_ADC, 0, NULL, 0),
 };
 
 static const struct snd_soc_dapm_route sun8i_codec_dapm_routes[] = {
-	/* Clock Routes */
-	{ "AIF1", NULL, "SYSCLK AIF1" },
-	{ "AIF1 PLL", NULL, "AIF1" },
-	{ "RST AIF1", NULL, "AIF1 PLL" },
-	{ "MODCLK AIF1", NULL, "RST AIF1" },
-	{ "DAC", NULL, "MODCLK AIF1" },
-	{ "ADC", NULL, "MODCLK AIF1" },
-
-	{ "RST DAC", NULL, "SYSCLK" },
-	{ "MODCLK DAC", NULL, "RST DAC" },
-	{ "DAC", NULL, "MODCLK DAC" },
-
-	{ "RST ADC", NULL, "SYSCLK" },
-	{ "MODCLK ADC", NULL, "RST ADC" },
-	{ "ADC", NULL, "MODCLK ADC" },
-
 	/* AIF "ADC" Output Routes */
 	{ "AIF1 Slot 0 Left ADC", NULL, "Left Digital ADC Mixer" },
 	{ "AIF1 Slot 0 Right ADC", NULL, "Right Digital ADC Mixer" },
 
-	{ "AIF1 Slot 0 Left ADC", NULL, "MODCLK AIF1" },
-	{ "AIF1 Slot 0 Right ADC", NULL, "MODCLK AIF1" },
+	{ "AIF1 Slot 0 Left ADC", NULL, "AIF1CLK" },
+	{ "AIF1 Slot 0 Right ADC", NULL, "AIF1CLK" },
 
 	/* AIF "DAC" Input Routes */
-	{ "AIF1 Slot 0 Left", NULL, "MODCLK AIF1" },
-	{ "AIF1 Slot 0 Right", NULL, "MODCLK AIF1" },
+	{ "AIF1 Slot 0 Left", NULL, "AIF1CLK" },
+	{ "AIF1 Slot 0 Right", NULL, "AIF1CLK" },
 
 	/* DAC Routes */
 	{ "DAC Left", NULL, "Left Digital DAC Mixer" },
@@ -535,8 +517,47 @@ static const struct snd_soc_dapm_route sun8i_codec_dapm_routes[] = {
 	  "ADC Left" },
 	{ "Right Digital ADC Mixer", "AIF1 Data Digital ADC Capture Switch",
 	  "ADC Right" },
+
+	/* Module Supply Routes */
+	{ "AIF1 Slot 0 Left ADC", NULL, "RST AIF1" },
+	{ "AIF1 Slot 0 Right ADC", NULL, "RST AIF1" },
+	{ "AIF1 Slot 0 Left", NULL, "RST AIF1" },
+	{ "AIF1 Slot 0 Right", NULL, "RST AIF1" },
+
+	{ "ADC", NULL, "RST ADC" },
+	{ "DAC", NULL, "RST DAC" },
+
+	/* Module Reset Routes */
+	{ "RST AIF1", NULL, "MODCLK AIF1" },
+	{ "RST ADC", NULL, "MODCLK ADC" },
+	{ "RST DAC", NULL, "MODCLK DAC" },
+
+	/* Module Clock Routes */
+	{ "MODCLK AIF1", NULL, "SYSCLK" },
+	{ "MODCLK ADC", NULL, "SYSCLK" },
+	{ "MODCLK DAC", NULL, "SYSCLK" },
+
+	/* Clock Supply Routes */
+	{ "SYSCLK", NULL, "AIF1CLK" },
 };
 
+static int sun8i_codec_component_probe(struct snd_soc_component *component)
+{
+	struct sun8i_codec *scodec = snd_soc_component_get_drvdata(component);
+
+	/* Set AIF1CLK clock source to PLL */
+	regmap_update_bits(scodec->regmap, SUN8I_SYSCLK_CTL,
+			   SUN8I_SYSCLK_CTL_AIF1CLK_SRC_MASK,
+			   SUN8I_SYSCLK_CTL_AIF1CLK_SRC_PLL);
+
+	/* Set SYSCLK clock source to AIF1CLK */
+	regmap_update_bits(scodec->regmap, SUN8I_SYSCLK_CTL,
+			   BIT(SUN8I_SYSCLK_CTL_SYSCLK_SRC),
+			   SUN8I_SYSCLK_CTL_SYSCLK_SRC_AIF1CLK);
+
+	return 0;
+}
+
 static const struct snd_soc_dai_ops sun8i_codec_dai_ops = {
 	.hw_params = sun8i_codec_hw_params,
 	.set_fmt = sun8i_set_fmt,
@@ -573,6 +594,7 @@ static const struct snd_soc_component_driver sun8i_soc_component = {
 	.num_dapm_widgets	= ARRAY_SIZE(sun8i_codec_dapm_widgets),
 	.dapm_routes		= sun8i_codec_dapm_routes,
 	.num_dapm_routes	= ARRAY_SIZE(sun8i_codec_dapm_routes),
+	.probe			= sun8i_codec_component_probe,
 	.idle_bias_on		= 1,
 	.use_pmdown_time	= 1,
 	.endianness		= 1,
-- 
2.24.1


  parent reply	other threads:[~2020-02-17  6:44 UTC|newest]

Thread overview: 69+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-02-17  6:42 [RFC PATCH 00/34] sun8i-codec fixes and new features Samuel Holland
2020-02-17  6:42 ` [RFC PATCH 01/34] ASoC: dt-bindings: Add a separate compatible for the A64 codec Samuel Holland
2020-02-17  9:49   ` Chen-Yu Tsai
2020-02-18  3:17     ` Samuel Holland
2020-02-26 15:18   ` Rob Herring
2020-02-17  6:42 ` [RFC PATCH 02/34] ASoC: sun8i-codec: LRCK is not inverted on A64 Samuel Holland
2020-02-17  9:50   ` Chen-Yu Tsai
2020-02-17 14:43   ` Mark Brown
2020-02-17  6:42 ` [RFC PATCH 03/34] arm64: dts: allwinner: a64: Fix the audio codec compatible Samuel Holland
2020-02-17 14:56   ` Mark Brown
2020-02-17  6:42 ` [RFC PATCH 04/34] ASoC: sun8i-codec: Remove unused dev from codec struct Samuel Holland
2020-02-17  7:41   ` Chen-Yu Tsai
2020-02-17 15:04   ` Mark Brown
2020-02-21 14:21   ` Applied "ASoC: sun8i-codec: Remove unused dev from codec struct" to the asoc tree Mark Brown
2020-02-17  6:42 ` [RFC PATCH 05/34] ASoC: sun8i-codec: Remove incorrect SND_SOC_DAIFMT_DSP_B Samuel Holland
2020-02-17  8:19   ` Chen-Yu Tsai
2020-02-17 15:02   ` Mark Brown
2020-02-18  1:35     ` Samuel Holland
2020-02-18 11:32       ` Mark Brown
2020-02-17  6:42 ` [RFC PATCH 06/34] ASoC: sun8i-codec: Fix setting DAI data format Samuel Holland
2020-02-17  8:23   ` Chen-Yu Tsai
2020-02-17 22:03   ` Applied "ASoC: sun8i-codec: Fix setting DAI data format" to the asoc tree Mark Brown
2020-02-17  6:42 ` [RFC PATCH 07/34] ASoC: sun8i-codec: Remove extraneous widgets Samuel Holland
2020-02-17  7:37   ` Chen-Yu Tsai
2020-02-17 15:05   ` Mark Brown
2020-02-17  6:42 ` [RFC PATCH 08/34] ASoC: sun8i-codec: Fix direction of AIF1 outputs Samuel Holland
2020-02-17  8:22   ` Chen-Yu Tsai
2020-02-17 15:09   ` Mark Brown
2020-02-18  1:44     ` Samuel Holland
2020-02-17  6:42 ` [RFC PATCH 09/34] ASoC: sun8i-codec: Fix broken DAPM routing Samuel Holland
2020-02-17 15:24   ` Mark Brown
2020-02-17  6:42 ` [RFC PATCH 10/34] ASoC: sun8i-codec: Advertise only hardware-supported rates Samuel Holland
2020-02-17 15:30   ` Mark Brown
2020-02-18  1:55     ` Samuel Holland
2020-02-17  6:42 ` [RFC PATCH 11/34] ASoC: sun8i-codec: Enforce parameter symmetry Samuel Holland
2020-02-17  6:42 ` [RFC PATCH 12/34] ASoC: sun8i-codec: Fix AIF1 MODCLK widget name Samuel Holland
2020-02-17  8:06   ` Chen-Yu Tsai
2020-02-17  6:42 ` [RFC PATCH 13/34] ASoC: sun8i-codec: Fix AIF1_ADCDAT_CTRL field names Samuel Holland
2020-02-17  7:58   ` Chen-Yu Tsai
2020-02-17  6:42 ` [RFC PATCH 14/34] ASoC: sun8i-codec: Fix AIF1_MXR_SRC " Samuel Holland
2020-02-17  7:57   ` Chen-Yu Tsai
2020-02-17  6:42 ` [RFC PATCH 15/34] ASoC: sun8i-codec: Fix ADC_DIG_CTRL field name Samuel Holland
2020-02-17  7:55   ` Chen-Yu Tsai
2020-02-17  6:42 ` [RFC PATCH 16/34] ASoC: sun8i-codec: Fix field bit number indentation Samuel Holland
2020-02-17  7:54   ` Chen-Yu Tsai
2020-02-17  6:42 ` [RFC PATCH 17/34] ASoC: sun8i-codec: Sort masks in a consistent order Samuel Holland
2020-02-17  7:59   ` Chen-Yu Tsai
2020-02-17  6:42 ` [RFC PATCH 18/34] ASoC: sun8i-codec: Allow all clock inversion permutations Samuel Holland
2020-02-17  6:42 ` [RFC PATCH 19/34] ASoC: sun8i-codec: Support mono DAI configurations Samuel Holland
2020-02-17  6:42 ` [RFC PATCH 20/34] ASoC: sun8i-codec: Support 8/20/24-bit word sizes Samuel Holland
2020-02-17  6:42 ` Samuel Holland [this message]
2020-02-17  6:42 ` [RFC PATCH 22/34] ASoC: sun8i-codec: Clean up AIF1 Slot 0 widgets Samuel Holland
2020-02-17  6:42 ` [RFC PATCH 23/34] ASoC: sun8i-codec: Clean up DAC widgets Samuel Holland
2020-02-17  6:42 ` [RFC PATCH 24/34] ASoC: sun8i-codec: Prepare to support multiple AIFs Samuel Holland
2020-02-17  6:42 ` [RFC PATCH 25/34] ASoC: sun8i-codec: Add support for AIF2 Samuel Holland
2020-02-17  6:42 ` [RFC PATCH 26/34] ASoC: sun8i-codec: Add support for AIF3 Samuel Holland
2020-02-17  6:42 ` [RFC PATCH 27/34] ASoC: sun8i-codec: Add AIF mono/stereo controls Samuel Holland
2020-02-17  6:42 ` [RFC PATCH 28/34] ASoC: sun8i-codec: Add AIF loopback controls Samuel Holland
2020-02-17  6:42 ` [RFC PATCH 29/34] ASoC: sun8i-codec: Add AIF, ADC, and DAC volume controls Samuel Holland
2020-02-17  6:42 ` [RFC PATCH 30/34] ASoC: dt-bindings: Bump sound-dai-cells on sun8i-codec Samuel Holland
2020-02-18 20:23   ` Rob Herring
2020-02-17  6:42 ` [RFC PATCH 31/34] ARM: dts: sun8i-a33: Allow using multiple codec DAIs Samuel Holland
2020-02-17  6:42 ` [RFC PATCH 32/34] arm64: dts: allwinner: a64: " Samuel Holland
2020-02-17  6:42 ` [RFC PATCH 33/34] arm64: dts: allwinner: a64: Allow multiple DAI links Samuel Holland
2020-02-17  6:42 ` [RFC PATCH 34/34] arm64: dts: allwinner: a64: Add pinmux for AIF2/AIF3 Samuel Holland
2020-02-17  9:14 ` [RFC PATCH 00/34] sun8i-codec fixes and new features Maxime Ripard
2020-02-17  9:44   ` Chen-Yu Tsai
2020-02-17 12:07     ` Maxime Ripard
2020-02-17 16:26 ` Mark Brown

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200217064250.15516-22-samuel@sholland.org \
    --to=samuel@sholland.org \
    --cc=alsa-devel@alsa-project.org \
    --cc=anarsoul@gmail.com \
    --cc=broonie@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=lgirdwood@gmail.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=mripard@kernel.org \
    --cc=mylene.josserand@free-electrons.com \
    --cc=perex@perex.cz \
    --cc=robh+dt@kernel.org \
    --cc=tiwai@suse.com \
    --cc=wens@csie.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).