[d-kernel] [PATCH 2/4] ASoC: AMD: acp3x-es8336-mach: add quirk override mclk freq
nickel на altlinux.org
nickel на altlinux.org
Ср Апр 5 19:59:41 MSK 2023
From: Vasiliy Kovalev <kovalev at altlinux.org>
add quirk for driver snd_soc_acp3x_es8336_mach and changed the contents
of the driver data to store the MCLK coefficient from the ACPI table
according to:
https://github.com/codepayne/linux-sound-huawei/issues/5#issuecomment-1383126104
also add the possibility of using this driver for models not listed in
the DMI match table when using quirk
the quirk is not limited to changing only the frequency, it can also be
used afterwards
example:
use "options snd_soc_acp3x_es8336_mach quirk=0x4"
for set MCLK FREQ 48 MHz
Signed-off-by: Vasiliy Kovalev <kovalev at altlinux.org>
Signed-off-by: Nikolai Kostrigin <nickel at altlinux.org>
---
sound/soc/amd/acp3x-es8336.c | 65 +++++++++++++++++++++++++++++++-----
1 file changed, 57 insertions(+), 8 deletions(-)
diff --git a/sound/soc/amd/acp3x-es8336.c b/sound/soc/amd/acp3x-es8336.c
index fd23afa50eb52..bb66ba1f03592 100644
--- a/sound/soc/amd/acp3x-es8336.c
+++ b/sound/soc/amd/acp3x-es8336.c
@@ -26,6 +26,22 @@
#define SND_CARD_NAME DRV_NAME
#define DUAL_CHANNEL 2
+#define SOC_ES8336_ACPI_MCLK_MASK (GENMASK(2, 0))
+
+#define SOC_ES8336_ACPI_MCLK_0 0 // 12.288 MHz - default
+#define SOC_ES8336_ACPI_MCLK_1 1 // 24.576 MHz
+#define SOC_ES8336_ACPI_MCLK_2 2 // 19.2 MHz
+#define SOC_ES8336_ACPI_MCLK_3 3 // 24 MHz
+#define SOC_ES8336_ACPI_MCLK_4 4 // 48 MHz
+
+#define ES8336_MCLK_FREQ (48000 * 256)
+
+static unsigned long quirk;
+static unsigned long quirk_mclk;
+static int quirk_override = -1;
+module_param_named(quirk, quirk_override, int, 0444);
+MODULE_PARM_DESC(quirk, "Board-specific quirk override");
+
struct acp3x_es8336_private {
/* struct acp3x_platform_info machine must always be
* the first entry in the structure,
@@ -57,7 +73,6 @@ static const struct snd_pcm_hw_constraint_list constraints_channels = {
.list = channels,
.mask = 0,
};
-#define ES8336_MCLK_FREQ (48000 * 1000)
static int acp3x_es8336_codec_startup(struct snd_pcm_substream *substream)
{
@@ -67,6 +82,8 @@ static int acp3x_es8336_codec_startup(struct snd_pcm_substream *substream)
struct acp3x_es8336_private *priv;
struct snd_soc_dai *codec_dai;
int ret;
+ unsigned int mclk_hz = ES8336_MCLK_FREQ;
+ static u8 only_one = 0;
runtime = substream->runtime;
rtd = asoc_substream_to_rtd(substream);
@@ -74,7 +91,16 @@ static int acp3x_es8336_codec_startup(struct snd_pcm_substream *substream)
machine = &priv->machine;
codec_dai = asoc_rtd_to_codec(rtd, 0);
- ret = snd_soc_dai_set_sysclk(codec_dai, 0, ES8336_MCLK_FREQ, SND_SOC_CLOCK_OUT);
+ if (quirk_mclk) {
+ if (!only_one) {
+ only_one = 1;
+ dev_info(rtd->dev, "overriding mclk %d Hz => %d Hz\n",
+ mclk_hz, (unsigned int)quirk_mclk);
+ }
+ mclk_hz = (unsigned int) quirk_mclk;
+ }
+
+ ret = snd_soc_dai_set_sysclk(codec_dai, 0, mclk_hz, SND_SOC_CLOCK_OUT);
if (ret < 0) {
dev_err(rtd->dev, "can't set codec sysclk: %d\n", ret);
return ret;
@@ -257,7 +283,6 @@ static const struct dmi_system_id acp3x_es8336_dmi_table[] = {
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "KLVL-WXXW"),
DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "M1010"),
},
- .driver_data = &acp3x_es8336,
},
{
.matches = {
@@ -265,7 +290,6 @@ static const struct dmi_system_id acp3x_es8336_dmi_table[] = {
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "KLVL-WXX9"),
DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "M1010"),
},
- .driver_data = &acp3x_es8336,
},
{
.matches = {
@@ -273,7 +297,7 @@ static const struct dmi_system_id acp3x_es8336_dmi_table[] = {
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "BOM-WXX9"),
DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "M1010"),
},
- .driver_data = &acp3x_es8336,
+ .driver_data = (void *)(SOC_ES8336_ACPI_MCLK_4),
},
{
.matches = {
@@ -281,7 +305,6 @@ static const struct dmi_system_id acp3x_es8336_dmi_table[] = {
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HVY-WXX9"),
DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "M1040"),
},
- .driver_data = &acp3x_es8336,
},
{}
};
@@ -293,7 +316,7 @@ static int acp3x_probe(struct platform_device *pdev)
const struct dmi_system_id *dmi_id;
dmi_id = dmi_first_match(acp3x_es8336_dmi_table);
- if (dmi_id && dmi_id->driver_data) {
+ if (dmi_id || quirk_override != -1) {
struct acp3x_es8336_private *priv;
struct snd_soc_card *card;
@@ -305,7 +328,33 @@ static int acp3x_probe(struct platform_device *pdev)
return -ENOMEM;
}
- card = (struct snd_soc_card *)dmi_id->driver_data;
+ if(dmi_id && dmi_id->driver_data)
+ quirk = (unsigned long)dmi_id->driver_data;
+ if(quirk_override != -1) {
+ dev_info(dev, "Overriding quirk 0x%lx => 0x%x\n",
+ quirk, quirk_override);
+ quirk = (unsigned long)quirk_override;
+ }
+ switch(quirk & SOC_ES8336_ACPI_MCLK_MASK) {
+ case SOC_ES8336_ACPI_MCLK_0:
+ break;
+ case SOC_ES8336_ACPI_MCLK_1:
+ quirk_mclk = 48000 * 512;
+ break;
+ case SOC_ES8336_ACPI_MCLK_2:
+ quirk_mclk = 48000 * 400;
+ break;
+ case SOC_ES8336_ACPI_MCLK_3:
+ quirk_mclk = 48000 * 500;
+ break;
+ case SOC_ES8336_ACPI_MCLK_4:
+ quirk_mclk = 48000 * 1000;
+ break;
+ default:
+ dev_warn(dev, "unexpected driver data, use mclk default\n");
+ }
+
+ card = &acp3x_es8336;
card->dev = &pdev->dev;
platform_set_drvdata(pdev, card);
--
2.33.5
Подробная информация о списке рассылки devel-kernel