[PATCH 0/3] ASoC: Intel: bytcr_rt5640: Add support for devices with only a headphone jack (no speakers/mic)
Hi All,
This series adds support for devices with only a headphone jack (no speakers/internal mic). Specifically this adds support for the Mele PCG03 Mini PC. But the new no-speakers and no-internal-mic quirks will likely be useful on other devices too.
Regards,
Hans
Some devices, like mini PCs/media/top-set boxes do not have any speakers at all, an example of the is the Mele PCG03 Mini PC.
Add a new BYT_RT5640_NO_SPEAKERS quirk-flag which when sets does not add speaker routes and modifies the components and the (optional) long_name strings to reflect that there are no speakers.
Cc: Rasmus Porsager rasmus@beat.dk Signed-off-by: Hans de Goede hdegoede@redhat.com --- sound/soc/intel/boards/bytcr_rt5640.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-)
diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c index 5520d7c80019..dce2df30d4c5 100644 --- a/sound/soc/intel/boards/bytcr_rt5640.c +++ b/sound/soc/intel/boards/bytcr_rt5640.c @@ -71,6 +71,7 @@ enum { #define BYT_RT5640_SSP0_AIF2 BIT(21) #define BYT_RT5640_MCLK_EN BIT(22) #define BYT_RT5640_MCLK_25MHZ BIT(23) +#define BYT_RT5640_NO_SPEAKERS BIT(24)
#define BYTCR_INPUT_DEFAULTS \ (BYT_RT5640_IN3_MAP | \ @@ -132,6 +133,8 @@ static void log_quirks(struct device *dev) dev_info(dev, "quirk JD_NOT_INV enabled\n"); if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) dev_info(dev, "quirk MONO_SPEAKER enabled\n"); + if (byt_rt5640_quirk & BYT_RT5640_NO_SPEAKERS) + dev_info(dev, "quirk NO_SPEAKERS enabled\n"); if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC) dev_info(dev, "quirk DIFF_MIC enabled\n"); if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) { @@ -946,7 +949,7 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime) ret = snd_soc_dapm_add_routes(&card->dapm, byt_rt5640_mono_spk_map, ARRAY_SIZE(byt_rt5640_mono_spk_map)); - } else { + } else if (!(byt_rt5640_quirk & BYT_RT5640_NO_SPEAKERS)) { ret = snd_soc_dapm_add_routes(&card->dapm, byt_rt5640_stereo_spk_map, ARRAY_SIZE(byt_rt5640_stereo_spk_map)); @@ -1188,6 +1191,7 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; static const char * const map_name[] = { "dmic1", "dmic2", "in1", "in3" }; + __maybe_unused const char *spk_type; const struct dmi_system_id *dmi_id; struct byt_rt5640_private *priv; struct snd_soc_acpi_mach *mach; @@ -1196,7 +1200,7 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) bool sof_parent; int ret_val = 0; int dai_index = 0; - int i; + int i, cfg_spk;
is_bytcr = false; priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); @@ -1335,16 +1339,24 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) } }
+ if (byt_rt5640_quirk & BYT_RT5640_NO_SPEAKERS) { + cfg_spk = 0; + spk_type = "none"; + } else if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) { + cfg_spk = 1; + spk_type = "mono"; + } else { + cfg_spk = 2; + spk_type = "stereo"; + } + snprintf(byt_rt5640_components, sizeof(byt_rt5640_components), - "cfg-spk:%s cfg-mic:%s", - (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) ? "1" : "2", + "cfg-spk:%d cfg-mic:%s", cfg_spk, map_name[BYT_RT5640_MAP(byt_rt5640_quirk)]); byt_rt5640_card.components = byt_rt5640_components; #if !IS_ENABLED(CONFIG_SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES) snprintf(byt_rt5640_long_name, sizeof(byt_rt5640_long_name), - "bytcr-rt5640-%s-spk-%s-mic", - (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) ? - "mono" : "stereo", + "bytcr-rt5640-%s-spk-%s-mic", spk_type, map_name[BYT_RT5640_MAP(byt_rt5640_quirk)]); byt_rt5640_card.long_name = byt_rt5640_long_name; #endif
Some devices, like mini PCs/media/top-set boxes do not have an internal microphone at all, an example of the is the Mele PCG03 Mini PC.
Add a new BYT_RT5640_NO_INTERNAL_MIC_MAP input-mapping for this, which does not add any internal-mic routes and modifies the components and the (optional) long_name strings to reflect this.
Cc: Rasmus Porsager rasmus@beat.dk Signed-off-by: Hans de Goede hdegoede@redhat.com --- sound/soc/intel/boards/bytcr_rt5640.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c index dce2df30d4c5..48d781faded1 100644 --- a/sound/soc/intel/boards/bytcr_rt5640.c +++ b/sound/soc/intel/boards/bytcr_rt5640.c @@ -35,6 +35,7 @@ enum { BYT_RT5640_DMIC2_MAP, BYT_RT5640_IN1_MAP, BYT_RT5640_IN3_MAP, + BYT_RT5640_NO_INTERNAL_MIC_MAP, };
enum { @@ -117,6 +118,9 @@ static void log_quirks(struct device *dev) case BYT_RT5640_IN3_MAP: dev_info(dev, "quirk IN3_MAP enabled\n"); break; + case BYT_RT5640_NO_INTERNAL_MIC_MAP: + dev_info(dev, "quirk NO_INTERNAL_MIC_MAP enabled\n"); + break; default: dev_err(dev, "quirk map 0x%x is not supported, microphone input will not work\n", map); break; @@ -876,8 +880,8 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime) struct snd_soc_card *card = runtime->card; struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card); struct snd_soc_component *component = asoc_rtd_to_codec(runtime, 0)->component; - const struct snd_soc_dapm_route *custom_map; - int num_routes; + const struct snd_soc_dapm_route *custom_map = NULL; + int num_routes = 0; int ret;
card->dapm.idle_bias_off = true; @@ -912,13 +916,14 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime) custom_map = byt_rt5640_intmic_in3_map; num_routes = ARRAY_SIZE(byt_rt5640_intmic_in3_map); break; + case BYT_RT5640_DMIC1_MAP: + custom_map = byt_rt5640_intmic_dmic1_map; + num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic1_map); + break; case BYT_RT5640_DMIC2_MAP: custom_map = byt_rt5640_intmic_dmic2_map; num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic2_map); break; - default: - custom_map = byt_rt5640_intmic_dmic1_map; - num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic1_map); }
ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes); @@ -1190,7 +1195,7 @@ struct acpi_chan_package { /* ACPICA seems to require 64 bit integers */ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; - static const char * const map_name[] = { "dmic1", "dmic2", "in1", "in3" }; + static const char * const map_name[] = { "dmic1", "dmic2", "in1", "in3", "none" }; __maybe_unused const char *spk_type; const struct dmi_system_id *dmi_id; struct byt_rt5640_private *priv;
Add a quirk for the Mele PCG03 Mini PC, being a Mini PC this device has no speakers and no internal microphone.
To make matters worse the speaker output pins are shorted (to gnd or to each other?) and SPKVDD is provided. So trying to output sound on the speakers leads to shorting SPKVDD, this leads to a power dip after which the codec is an unknown state. Sometimes it drops of the i2c bus, sometimes it does still respond to i2c transfers, but is otherwise not functional. TL;DR: trying to use the speaker outputs on this model is BAD.
Besides not having speakers / an internal mic, this is a Bay Trail CR device without a CHAN package in ACPI, so we default to SSP0-AIF2 as codec connection. But the device is actually using SSP0-AIF1, so we need to quirk that too.
Cc: Rasmus Porsager rasmus@beat.dk Signed-off-by: Hans de Goede hdegoede@redhat.com --- sound/soc/intel/boards/bytcr_rt5640.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c index 48d781faded1..2dee84578b90 100644 --- a/sound/soc/intel/boards/bytcr_rt5640.c +++ b/sound/soc/intel/boards/bytcr_rt5640.c @@ -620,6 +620,15 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { BYT_RT5640_SSP0_AIF1 | BYT_RT5640_MCLK_EN), }, + { /* Mele PCG03 Mini PC */ + .matches = { + DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Mini PC"), + DMI_EXACT_MATCH(DMI_BOARD_NAME, "Mini PC"), + }, + .driver_data = (void *)(BYT_RT5640_NO_INTERNAL_MIC_MAP | + BYT_RT5640_NO_SPEAKERS | + BYT_RT5640_SSP0_AIF1), + }, { /* MPMAN Converter 9, similar hw as the I.T.Works TW891 2-in-1 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "MPMAN"),
On 1/9/21 3:01 PM, Hans de Goede wrote:
Hi All,
This series adds support for devices with only a headphone jack (no speakers/internal mic). Specifically this adds support for the Mele PCG03 Mini PC. But the new no-speakers and no-internal-mic quirks will likely be useful on other devices too.
Yep, I have one device like this, will send the DMI quirk when I get a chance. I wish there was a way to query this information from ACPI, we'll probably need a long list of quirks instead. Thanks Hans!
Acked-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com
On Sat, 9 Jan 2021 22:01:16 +0100, Hans de Goede wrote:
This series adds support for devices with only a headphone jack (no speakers/internal mic). Specifically this adds support for the Mele PCG03 Mini PC. But the new no-speakers and no-internal-mic quirks will likely be useful on other devices too.
Regards,
[...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
Thanks!
[1/3] ASoC: Intel: bytcr_rt5640: Add new BYT_RT5640_NO_SPEAKERS quirk-flag commit: 1851ccf9e155b2a6f6cca1a7bd49325f5efbd5d2 [2/3] ASoC: Intel: bytcr_rt5640: Add new BYT_RT5640_NO_INTERNAL_MIC_MAP input-mapping commit: 46466ab68e752d054b4b7aece1bfadc9f9bbf272 [3/3] ASoC: Intel: bytcr_rt5640: Add quirk for the Mele PCG03 Mini PC commit: df33032146baefb29d7e61193738f39e454917e3
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 (3)
-
Hans de Goede
-
Mark Brown
-
Pierre-Louis Bossart