[PATCH 0/7] ASoC: rt5645: Add Acer Switch V 10 quirk + report quirks in components string
Hi all,
This patch-series adds a quirk for the Acer Switch V 10, which uses a DMIC on the DMIC2 input, rather then the default analog mic on IN2.
Most of the patches are actually for adding a component string with mic and speaker routing information so that the UCM profile can use this instead of duplicating all the DMI quirks in the UCM profile.
I've also submitted a alsa-ucm-config patch to add support for the components string.
Regards,
Hans
Hans de Goede (7): ASoC: rt5645: Drop double EF20 entry from dmi_platform_data[] ASoC: rt5645: Add platform-data for Acer Switch V 10 ASoC: rt5645: Refactor rt5645_parse_dt() ASoC: rt5645: Add rt5645_get_pdata() helper ASoC: rt5645: Add a rt5645_components() helper ASoC: rt5645: Add mono speaker information to the components string ASoC: Intel: cht_bsw_rt5645: Set card.components string
sound/soc/codecs/rt5645.c | 113 +++++++++++++++--------- sound/soc/codecs/rt5645.h | 3 + sound/soc/intel/boards/cht_bsw_rt5645.c | 8 ++ 3 files changed, 83 insertions(+), 41 deletions(-)
dmi_platform_data[] first contains a DMI entry matching:
DMI_MATCH(DMI_PRODUCT_NAME, "EF20"),
and then contains an identical entry except for the match being:
DMI_MATCH(DMI_PRODUCT_NAME, "EF20EA"),
Since these are partial (non exact) DMI matches the first match will also match any board with "EF20EA" in their DMI product-name, drop the second, redundant, entry.
Fixes: a4dae468cfdd ("ASoC: rt5645: Add ACPI-defined GPIO for ECS EF20 series") Cc: Chris Chiu chiu@endlessos.org Signed-off-by: Hans de Goede hdegoede@redhat.com --- sound/soc/codecs/rt5645.c | 8 -------- 1 file changed, 8 deletions(-)
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index 7938b52d741d..c7089c2f7c5c 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -3847,14 +3847,6 @@ static const struct dmi_system_id dmi_platform_data[] = { }, .driver_data = (void *)&ecs_ef20_platform_data, }, - { - .ident = "EF20EA", - .callback = cht_rt5645_ef20_quirk_cb, - .matches = { - DMI_MATCH(DMI_PRODUCT_NAME, "EF20EA"), - }, - .driver_data = (void *)&ecs_ef20_platform_data, - }, { } };
The Acer Switch V 10 uses the default jack-detect mode 3, but instead of using an analog microphone it is using a DMIC on dmic-data-pin 1, like other models following Intel's Braswell's reference design.
Add a DMI quirk pointing to the intel_braswell_platform_data for this.
Signed-off-by: Hans de Goede hdegoede@redhat.com --- sound/soc/codecs/rt5645.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index c7089c2f7c5c..20bbdf76ffd7 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -3847,6 +3847,14 @@ static const struct dmi_system_id dmi_platform_data[] = { }, .driver_data = (void *)&ecs_ef20_platform_data, }, + { + .ident = "Acer Switch V 10 (SW5-017)", + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SW5-017"), + }, + .driver_data = (void *)&intel_braswell_platform_data, + }, { } };
Refactor rt5645_parse_dt(), make it take a pointer to struct rt5645_platform_data as argument instead of passing in the complete rt5645_priv struct.
While at it also make it void since it always succeeds.
This is a preparation patch for factoring the code to get the platform-data out into a separate helper function.
Signed-off-by: Hans de Goede hdegoede@redhat.com --- sound/soc/codecs/rt5645.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-)
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index 20bbdf76ffd7..7d0ad5650b44 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -3869,18 +3869,12 @@ static bool rt5645_check_dp(struct device *dev) return false; }
-static int rt5645_parse_dt(struct rt5645_priv *rt5645, struct device *dev) +static void rt5645_parse_dt(struct device *dev, struct rt5645_platform_data *pdata) { - rt5645->pdata.in2_diff = device_property_read_bool(dev, - "realtek,in2-differential"); - device_property_read_u32(dev, - "realtek,dmic1-data-pin", &rt5645->pdata.dmic1_data_pin); - device_property_read_u32(dev, - "realtek,dmic2-data-pin", &rt5645->pdata.dmic2_data_pin); - device_property_read_u32(dev, - "realtek,jd-mode", &rt5645->pdata.jd_mode); - - return 0; + pdata->in2_diff = device_property_read_bool(dev, "realtek,in2-differential"); + device_property_read_u32(dev, "realtek,dmic1-data-pin", &pdata->dmic1_data_pin); + device_property_read_u32(dev, "realtek,dmic2-data-pin", &pdata->dmic2_data_pin); + device_property_read_u32(dev, "realtek,jd-mode", &pdata->jd_mode); }
static int rt5645_i2c_probe(struct i2c_client *i2c) @@ -3909,7 +3903,7 @@ static int rt5645_i2c_probe(struct i2c_client *i2c) if (pdata) rt5645->pdata = *pdata; else if (rt5645_check_dp(&i2c->dev)) - rt5645_parse_dt(rt5645, &i2c->dev); + rt5645_parse_dt(&i2c->dev, &rt5645->pdata); else rt5645->pdata = jd_mode3_platform_data;
Add a rt5645_get_pdata() helper function which retreives the platform-data and overrides it with the quirks module parameter if that is set.
This is a preparation patch for adding the rt5645_components() function.
Signed-off-by: Hans de Goede hdegoede@redhat.com --- sound/soc/codecs/rt5645.c | 51 ++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 25 deletions(-)
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index 7d0ad5650b44..f79a447eaffe 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -3877,10 +3877,33 @@ static void rt5645_parse_dt(struct device *dev, struct rt5645_platform_data *pda device_property_read_u32(dev, "realtek,jd-mode", &pdata->jd_mode); }
+static void rt5645_get_pdata(struct device *codec_dev, struct rt5645_platform_data *pdata) +{ + const struct dmi_system_id *dmi_data; + + dmi_data = dmi_first_match(dmi_platform_data); + if (dmi_data) { + dev_info(codec_dev, "Detected %s platform\n", dmi_data->ident); + *pdata = *((struct rt5645_platform_data *)dmi_data->driver_data); + } else if (rt5645_check_dp(codec_dev)) { + rt5645_parse_dt(codec_dev, pdata); + } else { + *pdata = jd_mode3_platform_data; + } + + if (quirk != -1) { + pdata->in2_diff = QUIRK_IN2_DIFF(quirk); + pdata->level_trigger_irq = QUIRK_LEVEL_IRQ(quirk); + pdata->inv_jd1_1 = QUIRK_INV_JD1_1(quirk); + pdata->inv_hp_pol = QUIRK_INV_HP_POL(quirk); + pdata->jd_mode = QUIRK_JD_MODE(quirk); + pdata->dmic1_data_pin = QUIRK_DMIC1_DATA_PIN(quirk); + pdata->dmic2_data_pin = QUIRK_DMIC2_DATA_PIN(quirk); + } +} + static int rt5645_i2c_probe(struct i2c_client *i2c) { - struct rt5645_platform_data *pdata = NULL; - const struct dmi_system_id *dmi_data; struct rt5645_priv *rt5645; int ret, i; unsigned int val; @@ -3893,29 +3916,7 @@ static int rt5645_i2c_probe(struct i2c_client *i2c)
rt5645->i2c = i2c; i2c_set_clientdata(i2c, rt5645); - - dmi_data = dmi_first_match(dmi_platform_data); - if (dmi_data) { - dev_info(&i2c->dev, "Detected %s platform\n", dmi_data->ident); - pdata = dmi_data->driver_data; - } - - if (pdata) - rt5645->pdata = *pdata; - else if (rt5645_check_dp(&i2c->dev)) - rt5645_parse_dt(&i2c->dev, &rt5645->pdata); - else - rt5645->pdata = jd_mode3_platform_data; - - if (quirk != -1) { - rt5645->pdata.in2_diff = QUIRK_IN2_DIFF(quirk); - rt5645->pdata.level_trigger_irq = QUIRK_LEVEL_IRQ(quirk); - rt5645->pdata.inv_jd1_1 = QUIRK_INV_JD1_1(quirk); - rt5645->pdata.inv_hp_pol = QUIRK_INV_HP_POL(quirk); - rt5645->pdata.jd_mode = QUIRK_JD_MODE(quirk); - rt5645->pdata.dmic1_data_pin = QUIRK_DMIC1_DATA_PIN(quirk); - rt5645->pdata.dmic2_data_pin = QUIRK_DMIC2_DATA_PIN(quirk); - } + rt5645_get_pdata(&i2c->dev, &rt5645->pdata);
if (has_acpi_companion(&i2c->dev)) { if (cht_rt5645_gpios) {
The rt5645 codec driver uses DMI quirks to configure the DMIC data-pins, which means that it knows which DMIC interface is used on a specific device.
ATM we duplicate this DMI matching inside the UCM profiles to select the right DMIC interface. Add a rt5645_components() helper which the machine-driver can use to set the components string of the card so that UCM can get the info from the components string.
This way we only need to add new DMI quirks in one place.
Signed-off-by: Hans de Goede hdegoede@redhat.com --- sound/soc/codecs/rt5645.c | 24 ++++++++++++++++++++++++ sound/soc/codecs/rt5645.h | 3 +++ 2 files changed, 27 insertions(+)
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index f79a447eaffe..4f3ef004f555 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -3902,6 +3902,30 @@ static void rt5645_get_pdata(struct device *codec_dev, struct rt5645_platform_da } }
+const char *rt5645_components(struct device *codec_dev) +{ + struct rt5645_platform_data pdata = { }; + static char buf[32]; + const char *mic; + int spk = 2; + + rt5645_get_pdata(codec_dev, &pdata); + + if (pdata.dmic1_data_pin && pdata.dmic2_data_pin) + mic = "dmics12"; + else if (pdata.dmic1_data_pin) + mic = "dmic1"; + else if (pdata.dmic2_data_pin) + mic = "dmic2"; + else + mic = "in2"; + + snprintf(buf, sizeof(buf), "cfg-spk:%d cfg-mic:%s", spk, mic); + + return buf; +} +EXPORT_SYMBOL_GPL(rt5645_components); + static int rt5645_i2c_probe(struct i2c_client *i2c) { struct rt5645_priv *rt5645; diff --git a/sound/soc/codecs/rt5645.h b/sound/soc/codecs/rt5645.h index ac3de6f3bc2f..90816b2c5489 100644 --- a/sound/soc/codecs/rt5645.h +++ b/sound/soc/codecs/rt5645.h @@ -2201,4 +2201,7 @@ int rt5645_sel_asrc_clk_src(struct snd_soc_component *component, int rt5645_set_jack_detect(struct snd_soc_component *component, struct snd_soc_jack *hp_jack, struct snd_soc_jack *mic_jack, struct snd_soc_jack *btn_jack); + +const char *rt5645_components(struct device *codec_dev); + #endif /* __RT5645_H__ */
The GPD Win and Teclast X80 Pro both only have 1 speaker add information about this to the components string.
Signed-off-by: Hans de Goede hdegoede@redhat.com --- sound/soc/codecs/rt5645.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index 4f3ef004f555..e109ee2e321c 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -428,6 +428,9 @@ struct rt5645_platform_data { /* Invert HP detect status polarity */ bool inv_hp_pol;
+ /* Only 1 speaker connected */ + bool mono_speaker; + /* Value to assign to snd_soc_card.long_name */ const char *long_name;
@@ -3653,6 +3656,7 @@ static const struct rt5645_platform_data buddy_platform_data = { static const struct rt5645_platform_data gpd_win_platform_data = { .jd_mode = 3, .inv_jd1_1 = true, + .mono_speaker = true, .long_name = "gpd-win-pocket-rt5645", /* The GPD pocket has a diff. mic, for the win this does not matter. */ .in2_diff = true, @@ -3676,6 +3680,11 @@ static const struct rt5645_platform_data lenovo_ideapad_miix_310_pdata = { .in2_diff = true, };
+static const struct rt5645_platform_data jd_mode3_monospk_platform_data = { + .jd_mode = 3, + .mono_speaker = true, +}; + static const struct rt5645_platform_data jd_mode3_platform_data = { .jd_mode = 3, }; @@ -3795,7 +3804,7 @@ static const struct dmi_system_id dmi_platform_data[] = { DMI_MATCH(DMI_SYS_VENDOR, "TECLAST"), DMI_MATCH(DMI_PRODUCT_NAME, "X80 Pro"), }, - .driver_data = (void *)&jd_mode3_platform_data, + .driver_data = (void *)&jd_mode3_monospk_platform_data, }, { .ident = "Lenovo Ideapad Miix 310", @@ -3911,6 +3920,9 @@ const char *rt5645_components(struct device *codec_dev)
rt5645_get_pdata(codec_dev, &pdata);
+ if (pdata.mono_speaker) + spk = 1; + if (pdata.dmic1_data_pin && pdata.dmic2_data_pin) mic = "dmics12"; else if (pdata.dmic1_data_pin)
Set the card.components string using the new rt5645_components() helper which returns a components string based on the DMI quirks inside the rt5645 codec driver.
Signed-off-by: Hans de Goede hdegoede@redhat.com --- sound/soc/intel/boards/cht_bsw_rt5645.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/sound/soc/intel/boards/cht_bsw_rt5645.c b/sound/soc/intel/boards/cht_bsw_rt5645.c index df23a581c10e..c952a96cde7e 100644 --- a/sound/soc/intel/boards/cht_bsw_rt5645.c +++ b/sound/soc/intel/boards/cht_bsw_rt5645.c @@ -534,6 +534,7 @@ static int snd_cht_mc_probe(struct platform_device *pdev) const char *platform_name; struct cht_mc_private *drv; struct acpi_device *adev; + struct device *codec_dev; bool sof_parent; bool found = false; bool is_bytcr = false; @@ -583,7 +584,14 @@ static int snd_cht_mc_probe(struct platform_device *pdev) "i2c-%s", acpi_dev_name(adev)); cht_dailink[dai_index].codecs->name = cht_rt5645_codec_name; } + /* acpi_get_first_physical_node() returns a borrowed ref, no need to deref */ + codec_dev = acpi_get_first_physical_node(adev); acpi_dev_put(adev); + if (!codec_dev) + return -EPROBE_DEFER; + + snd_soc_card_chtrt5645.components = rt5645_components(codec_dev); + snd_soc_card_chtrt5650.components = rt5645_components(codec_dev);
/* * swap SSP0 if bytcr is detected
On Sun, 26 Nov 2023 22:40:17 +0100, Hans de Goede wrote:
This patch-series adds a quirk for the Acer Switch V 10, which uses a DMIC on the DMIC2 input, rather then the default analog mic on IN2.
Most of the patches are actually for adding a component string with mic and speaker routing information so that the UCM profile can use this instead of duplicating all the DMI quirks in the UCM profile.
[...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
Thanks!
[1/7] ASoC: rt5645: Drop double EF20 entry from dmi_platform_data[] commit: 51add1687f39292af626ac3c2046f49241713273 [2/7] ASoC: rt5645: Add platform-data for Acer Switch V 10 commit: 8f28e1996a786a7538d65e5258d3eecb92943673 [3/7] ASoC: rt5645: Refactor rt5645_parse_dt() commit: f72a9c2b8f1487181302d69fb82d5c76226be3fb [4/7] ASoC: rt5645: Add rt5645_get_pdata() helper commit: b4635b9cd9ae48050d72b645cc53175788bebf52 [5/7] ASoC: rt5645: Add a rt5645_components() helper commit: 4cd7654553b3cf1ce5a7560f0492f0431785dfae [6/7] ASoC: rt5645: Add mono speaker information to the components string commit: 8184e1db699befc5101bcfe401283becfc228a0b [7/7] ASoC: Intel: cht_bsw_rt5645: Set card.components string commit: f87b4402163be352601f7a012ab0d8dba7ecc64d
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
participants (2)
-
Hans de Goede
-
Mark Brown