mirror of
https://abf.rosa.ru/djam/kernel-6.6.git
synced 2025-02-24 11:22:47 +00:00
97 lines
3.4 KiB
Diff
97 lines
3.4 KiB
Diff
From 16352cc3e81586ed5964c0903e78204860955b49 Mon Sep 17 00:00:00 2001
|
|
From: Marian Postevca <posteuca@mutex.one>
|
|
Date: Wed, 30 Aug 2023 01:01:14 +0300
|
|
Subject: [PATCH 406/415] ASoC: es8316: Enable support for MCLK div by 2
|
|
|
|
To properly support a line of Huawei laptops with an AMD CPU
|
|
and an ES8336 codec connected to the ACP3X module, we need
|
|
to enable the codec option to divide the MCLK by 2.
|
|
This is needed because for at least one SKU that has a 48Mhz
|
|
MCLK the sound is distorted unless the MCLK div by 2 option
|
|
is enabled.
|
|
|
|
The option to divide the MCLK will first be tried. If no suitable
|
|
clocking can be generated from this frequency, then the normal
|
|
non-halved MCLK frequency will be tried.
|
|
|
|
Signed-off-by: Marian Postevca <posteuca@mutex.one>
|
|
Link: https://lore.kernel.org/r/20230829220116.1159-4-posteuca@mutex.one
|
|
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
---
|
|
sound/soc/codecs/es8316.c | 45 +++++++++++++++++++++++++++++----------
|
|
sound/soc/codecs/es8316.h | 3 +++
|
|
2 files changed, 37 insertions(+), 11 deletions(-)
|
|
|
|
diff --git a/sound/soc/codecs/es8316.c b/sound/soc/codecs/es8316.c
|
|
index a1c3e10c3cf1..e53b2856d625 100644
|
|
--- a/sound/soc/codecs/es8316.c
|
|
+++ b/sound/soc/codecs/es8316.c
|
|
@@ -469,19 +469,42 @@ static int es8316_pcm_hw_params(struct snd_pcm_substream *substream,
|
|
u8 bclk_divider;
|
|
u16 lrck_divider;
|
|
int i;
|
|
+ unsigned int clk = es8316->sysclk / 2;
|
|
+ bool clk_valid = false;
|
|
+
|
|
+ /* We will start with halved sysclk and see if we can use it
|
|
+ * for proper clocking. This is to minimise the risk of running
|
|
+ * the CODEC with a too high frequency. We have an SKU where
|
|
+ * the sysclk frequency is 48Mhz and this causes the sound to be
|
|
+ * sped up. If we can run with a halved sysclk, we will use it,
|
|
+ * if we can't use it, then full sysclk will be used.
|
|
+ */
|
|
+ do {
|
|
+ /* Validate supported sample rates that are autodetected from MCLK */
|
|
+ for (i = 0; i < ARRAY_SIZE(supported_mclk_lrck_ratios); i++) {
|
|
+ const unsigned int ratio = supported_mclk_lrck_ratios[i];
|
|
+
|
|
+ if (clk % ratio != 0)
|
|
+ continue;
|
|
+ if (clk / ratio == params_rate(params))
|
|
+ break;
|
|
+ }
|
|
+ if (i == ARRAY_SIZE(supported_mclk_lrck_ratios)) {
|
|
+ if (clk == es8316->sysclk)
|
|
+ return -EINVAL;
|
|
+ clk = es8316->sysclk;
|
|
+ } else {
|
|
+ clk_valid = true;
|
|
+ }
|
|
+ } while (!clk_valid);
|
|
|
|
- /* Validate supported sample rates that are autodetected from MCLK */
|
|
- for (i = 0; i < ARRAY_SIZE(supported_mclk_lrck_ratios); i++) {
|
|
- const unsigned int ratio = supported_mclk_lrck_ratios[i];
|
|
-
|
|
- if (es8316->sysclk % ratio != 0)
|
|
- continue;
|
|
- if (es8316->sysclk / ratio == params_rate(params))
|
|
- break;
|
|
+ if (clk != es8316->sysclk) {
|
|
+ snd_soc_component_update_bits(component, ES8316_CLKMGR_CLKSW,
|
|
+ ES8316_CLKMGR_CLKSW_MCLK_DIV,
|
|
+ ES8316_CLKMGR_CLKSW_MCLK_DIV);
|
|
}
|
|
- if (i == ARRAY_SIZE(supported_mclk_lrck_ratios))
|
|
- return -EINVAL;
|
|
- lrck_divider = es8316->sysclk / params_rate(params);
|
|
+
|
|
+ lrck_divider = clk / params_rate(params);
|
|
bclk_divider = lrck_divider / 4;
|
|
switch (params_format(params)) {
|
|
case SNDRV_PCM_FORMAT_S16_LE:
|
|
diff --git a/sound/soc/codecs/es8316.h b/sound/soc/codecs/es8316.h
|
|
index c335138e2837..0ff16f948690 100644
|
|
--- a/sound/soc/codecs/es8316.h
|
|
+++ b/sound/soc/codecs/es8316.h
|
|
@@ -129,4 +129,7 @@
|
|
#define ES8316_GPIO_FLAG_GM_NOT_SHORTED 0x02
|
|
#define ES8316_GPIO_FLAG_HP_NOT_INSERTED 0x04
|
|
|
|
+/* ES8316_CLKMGR_CLKSW */
|
|
+#define ES8316_CLKMGR_CLKSW_MCLK_DIV 0x80
|
|
+
|
|
#endif
|
|
--
|
|
2.40.1
|
|
|