[PATCH] ASoC: Intel: soc-acpi-intel-ptl-match: add rt721_l3_rt1320_l3
Sataporn <[email protected]>
| Newsgroups | gmane.linux.sound,gmane.linux.kernel |
|---|---|
| Message-ID | <[email protected]> |
The Lenovo Yoga Slim 7i 14IPH11 (DMI product 83QM) drives four speakers from two amplifiers on SoundWire link 3: sdw:0:3:025d:0721:01 RT721, CompanionAmp function only sdw:0:3:025d:1320:01 RT1320, SmartAmp function This chassis has no headset jack, and the microphones are the PCH DMIC array, so no jack or mic function is described for either peripheral. The Panther Lake match table has no RT721 entry at all: the RT1320 is described on links 1, 2 and 3, but only ever paired with RT712, RT713 or RT722. This layout therefore matches nothing and the driver falls back to the default SoundWire machine with function topologies. That fallback misbehaves here, because the firmware also declares a peripheral that is not fitted: sdw:0:3:025d:0722:01 RT722, never attaches, reported UNATTACHED Its ACPI device (SWD0, _ADR 0x000330025D072201, in SSDT "LENOVO CB-01") has no _STA method, so it is enumerated unconditionally on every SKU sharing this mainboard (LNVNB161216), which also ships in CS42L43 and RT722 variants. It carries UAJ, SmartMic, HID and SmartAmp functions, which appear to describe a sibling SKU that has a headset jack. The default machine driver selects it for the jack, microphone and speaker functions: Components : ... cfg-amp:3 ... spk:rt721 rt1320 rt722 hs:rt722 mic:rt722 and every stream then fails when its ports are programmed: rt722-sdca sdw:0:3:025d:0722:01: DPN_PortCtrl register write failed for port 1 soundwire sdw-master-0-3: Program transport params failed: -61 soundwire sdw-master-0-3: Program params failed: -61 SDW3-Playback-SimpleJack: ASoC error (-61): at snd_soc_link_prepare() Speakers and microphones are silent; only HDMI works. Add an entry describing the two amplifiers. They share aggregation group 1, following the existing rt712_vb_l3_rt1320_l3 entry: with separate groups each device asks for a DAI link named "SDW3-Playback-SmartAmp" and the second registration fails with -EEXIST. The RT721 needs its own speaker endpoint rather than spk_l_endpoint, because the endpoint number indexes the codec DAI array and the RT721 exposes its amplifier as endpoint 1: endpoint 0 is the jack, so reusing spk_l_endpoint creates a jack DAI link and no amplifier at all. No monolithic topology exists for this combination, so sof_tplg_filename is set to the "dummy" name that hda_sdw_machine_select() already uses for the default machine. Without it, load_topology() runs with no_fallback clear, and sof_sdw_get_tplg_files() abandons the function topologies entirely on reaching the SSP2-BT link, which has no separate topology yet: sof_sdw sof_sdw: dai_link SSP2-BT id 8 sof_sdw sof_sdw: dai_link SSP2-BT is not supported by separated tplg yet falling back to a monolithic file that does not exist. Marking the absence of a fallback lets that link be skipped instead, and keeps BT offload enabled. snd_soc_acpi_sdw_link_slaves_found() only requires the peripherals named in the table to be present, so the unfitted RT722 does not prevent the match. An explicit entry stops the machine driver selecting it, without needing a quirk for the firmware bug itself. Signed-off-by: Sataporn <[email protected]> --- alsa-info with this patch applied: https://alsa-project.org/db/?f=8b9e4c24389cc520c77b3ece54edcbfbb50d07c6 diff --git a/sound/soc/intel/common/soc-acpi-intel-ptl-match.c b/sound/soc/intel/common/soc-acpi-intel-ptl-match.c index f7694b2..c3ce060 100644 --- a/sound/soc/intel/common/soc-acpi-intel-ptl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-ptl-match.c @@ -92,6 +92,18 @@ static const struct snd_soc_acpi_endpoint spk_r_endpoint = { .group_id = 1, }; +/* + * The RT721 exposes its amplifier as endpoint 1; endpoint 0 is the jack and + * endpoint 2 the DMIC array, neither of which is wired up on boards that use + * the codec as a speaker amplifier only. + */ +static const struct snd_soc_acpi_endpoint rt721_spk_l_endpoint = { + .num = 1, + .aggregated = 1, + .group_position = 0, + .group_id = 1, +}; + static const struct snd_soc_acpi_endpoint jack_dmic_endpoints[] = { /* Jack Endpoint */ { @@ -211,6 +223,15 @@ static const struct snd_soc_acpi_adr_device rt712_vb_3_group1_adr[] = { } }; +static const struct snd_soc_acpi_adr_device rt721_3_group1_adr[] = { + { + .adr = 0x000330025D072101ull, + .num_endpoints = 1, + .endpoints = &rt721_spk_l_endpoint, + .name_prefix = "rt721" + } +}; + static const struct snd_soc_acpi_adr_device rt713_vb_2_adr[] = { { .adr = 0x000230025d071301ull, @@ -437,6 +458,20 @@ static const struct snd_soc_acpi_link_adr ptl_sdw_rt712_vb_l3_rt1320_l3[] = { {} }; +static const struct snd_soc_acpi_link_adr ptl_sdw_rt721_l3_rt1320_l3[] = { + { + .mask = BIT(3), + .num_adr = ARRAY_SIZE(rt721_3_group1_adr), + .adr_d = rt721_3_group1_adr, + }, + { + .mask = BIT(3), + .num_adr = ARRAY_SIZE(rt1320_3_group1_adr), + .adr_d = rt1320_3_group1_adr, + }, + {} +}; + /* this table is used when there is no I2S codec present */ struct snd_soc_acpi_mach snd_soc_acpi_intel_ptl_sdw_machines[] = { /* Order Priority: mockup > most links > most bit link-mask > alphabetical */ @@ -531,6 +566,19 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_ptl_sdw_machines[] = { .sof_tplg_filename = "sof-ptl-rt712-l3-rt1320-l3.tplg", .get_function_tplg_files = sof_sdw_get_tplg_files, }, + { + .link_mask = BIT(3), + .links = ptl_sdw_rt721_l3_rt1320_l3, + .drv_name = "sof_sdw", + /* + * No monolithic topology exists for this combination; the + * "dummy" name marks that, so the function topologies are + * used and functions without one are skipped rather than + * failing the card. + */ + .sof_tplg_filename = "sof-ptl-dummy.tplg", + .get_function_tplg_files = sof_sdw_get_tplg_files, + }, {}, }; EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_ptl_sdw_machines); -- 2.43.0 -- 2.51.0