* [PATCH v3 0/3] Add ASoC machine driver for Cherryview tablets with RT5677
@ 2026-06-10 23:51 Yauhen Kharuzhy
2026-06-10 23:51 ` [PATCH v3 1/3] ASoC: Intel: soc-acpi-cht: Unify device quirks Yauhen Kharuzhy
` (2 more replies)
0 siblings, 3 replies; 11+ messages in thread
From: Yauhen Kharuzhy @ 2026-06-10 23:51 UTC (permalink / raw)
To: Cezary Rojewski, Liam Girdwood, Peter Ujfalusi, Bard Liao,
Ranjani Sridharan, Kai Vehmanen, Pierre-Louis Bossart, Mark Brown,
Jaroslav Kysela, Takashi Iwai
Cc: linux-sound, linux-kernel, Hans de Goede, Yauhen Kharuzhy
This is the third iteration of my submission for sound support for Lenovo
Yoga Book YB1-X90/X91 tablets.
These are Cherry Trail-based platforms that use the RT5677 codec and
TS3A227E jack detection IC.
The YB1-X90 is an Android-designated device and has incorrect ACPI entries
for many onboard peripherals, including sound devices. The YB1-X91 has a
DSDT node for the codec, and the same node is shared with the TS3A227E
jack detection IC (see below).
Matching with ACPI entries is somewhat tricky; see the corresponding
commit. Jack detection IC info is defined in the x86-android-tablets driver
for both platforms to simplify the code.
The ASoC machine driver is called 'cht_rt5677' but has some
device-specific things hardcoded because no other known
Cherry Trail-based platforms use an RT5677 codec.
v3:
- Rename cht_yogabook driver to cht_rt5677;
- Allocate snd_soc_card structure dynamically;
- Reset the codec name in the global dailink array back to the default
at driver remove() method to prevent use-after-free error;
- Apply small fixes like removing code duplication and renaming variables in
the probe method;
- Remove support for SOF;
- Skip checking if ctx->mclk is valid since probe() will fail if not;
- Ensure error codes are included in error messages during initialization;
- Eliminate debug messages;
- Split cht_rt5677_platform_clock_control() function into enable/disable
subroutines;
- Move GPIOs initialization from codec init to probe and use gpiod_*
functions instead of devm_gpiod_* versions because GPIOs are linked to
another device;
- Rename variable 'k' to 'kctl' for struct snd_kcontrol arguments;
- Remove ambiguous copyright statements;
- Switch from using *-objs to *-y in the Makefile;
- Correct alignment warnings reported by checkpatch;
- Update ACPI matching code: rename cht_quirk_nocodec() to cht_quirk_strict(),
and use a default entry for the YB1-X91 tablet.
- Link to v2: https://lore.kernel.org/r/20260301-asoc-yogabook-v2-v2-0-adcc7ed40985@gmail.com
v2:
cht_yogabook driver:
- Remove likely obsolete code from the driver: GPIO magic manipulations
when enabling the speaker amplifier and msleep() calls when turning
the speaker/headphones on and off.
- Remove MICBIAS1 manipulation on headphone jack insertion (click
prevention): the TS3A227E should handle it by itself.
- Rename struct cht_mc_private to cht_yb_private.
ACPI matching code:
- Split the changes into two commits: reworking existing entries and adding
new ones.
- Use dmi_system_id.driver_data to specify matched machine data instead
of callbacks.
For reference, there is an ACPI node for sound configuration from YB1-X91
DSDT below:
HID: 10EC5677
_CRS resources:
I2C devices:
0: rt5677 codec
1: ts3a227e jack detection IC
GPIOs:
0: rt5677 codec reset
1: rt5677 codec pow-ldo2
2: speaker enable
INTs:
0: rt5677 codec
1: ts3a227e jack detection IC
SPI device:
0: rt5677 codec SPI connection
Decompiled fragment of ACPI dump:
Device (RTEK)
{
Name (_ADR, Zero) // _ADR: Address
Name (_HID, "10EC5677") // _HID: Hardware ID
Name (_CID, "10EC5677") // _CID: Compatible ID
Name (_DDN, "Realtek IIS Audio Codec") // _DDN: DOS Device Name
Name (_SUB, "17AA7005") // _SUB: Subsystem ID
Name (_UID, One) // _UID: Unique ID
Name (_PR0, Package (0x01) // _PR0: Power Resources for D0
{
CLK3
})
Name (CHAN, Package (0x02)
{
One,
0x0124F800
})
Method (_CRS, 0, NotSerialized) // _CRS: Current Resource Settings
{
Name (SBUF, ResourceTemplate ()
{
I2cSerialBusV2 (0x002C, ControllerInitiated, 0x000186A0,
AddressingMode7Bit, "\\_SB.PCI0.I2C1",
0x00, ResourceConsumer, , Exclusive,
)
I2cSerialBusV2 (0x003B, ControllerInitiated, 0x000186A0,
AddressingMode7Bit, "\\_SB.PCI0.I2C1",
0x00, ResourceConsumer, , Exclusive,
)
GpioIo (Exclusive, PullDefault, 0x0000, 0x0000, IoRestrictionOutputOnly,
"\\_SB.GPO3", 0x00, ResourceConsumer, ,
)
{ // Pin list
0x0019
}
GpioIo (Exclusive, PullDefault, 0x0000, 0x0000, IoRestrictionOutputOnly,
"\\_SB.GPO3", 0x00, ResourceConsumer, ,
)
{ // Pin list
0x0012
}
GpioIo (Exclusive, PullDefault, 0x0000, 0x0000, IoRestrictionOutputOnly,
"\\_SB.GPO3", 0x00, ResourceConsumer, ,
)
{ // Pin list
0x0030
}
GpioInt (Edge, ActiveLow, Exclusive, PullNone, 0x0000,
"\\_SB.GPO0", 0x00, ResourceConsumer, ,
)
{ // Pin list
0x005B
}
GpioInt (Edge, ActiveLow, Exclusive, PullNone, 0x0000,
"\\_SB.GPO0", 0x00, ResourceConsumer, ,
)
{ // Pin list
0x004D
}
SpiSerialBusV2 (0x0001, PolarityLow, FourWireMode, 0x08,
ControllerInitiated, 0x003D0900, ClockPolarityHigh,
ClockPhaseSecond, "\\_SB.PCI0.SPI1",
0x00, ResourceConsumer, , Exclusive,
)
})
Return (SBUF) /* \_SB_.PCI0.I2C1.RTEK._CRS.SBUF */
}
}
Signed-off-by: Yauhen Kharuzhy <jekhor@gmail.com>
---
Yauhen Kharuzhy (3):
ASoC: Intel: soc-acpi-cht: Unify device quirks
ASoC: Intel: soc-acpi-cht: Add Lenovo Yoga Book entries
ASoC: Intel: Add cht_rt5677 driver
sound/soc/intel/boards/Kconfig | 18 +
sound/soc/intel/boards/Makefile | 2 +
sound/soc/intel/boards/cht_rt5677.c | 564 ++++++++++++++++++++++
sound/soc/intel/common/soc-acpi-intel-cht-match.c | 121 ++---
4 files changed, 648 insertions(+), 57 deletions(-)
---
base-commit: 94a662ada263eb2238b85e1eb4b21fd03b9b5fa2
change-id: 20260219-asoc-yogabook-v2-70c146371d20
Best regards,
--
Yauhen Kharuzhy
^ permalink raw reply [flat|nested] 11+ messages in thread* [PATCH v3 1/3] ASoC: Intel: soc-acpi-cht: Unify device quirks 2026-06-10 23:51 [PATCH v3 0/3] Add ASoC machine driver for Cherryview tablets with RT5677 Yauhen Kharuzhy @ 2026-06-10 23:51 ` Yauhen Kharuzhy 2026-06-11 8:47 ` Cezary Rojewski 2026-06-11 14:10 ` Mark Brown 2026-06-10 23:51 ` [PATCH v3 2/3] ASoC: Intel: soc-acpi-cht: Add Lenovo Yoga Book entries Yauhen Kharuzhy 2026-06-10 23:51 ` [PATCH v3 3/3] ASoC: Intel: Add cht_rt5677 driver Yauhen Kharuzhy 2 siblings, 2 replies; 11+ messages in thread From: Yauhen Kharuzhy @ 2026-06-10 23:51 UTC (permalink / raw) To: Cezary Rojewski, Liam Girdwood, Peter Ujfalusi, Bard Liao, Ranjani Sridharan, Kai Vehmanen, Pierre-Louis Bossart, Mark Brown, Jaroslav Kysela, Takashi Iwai Cc: linux-sound, linux-kernel, Hans de Goede, Yauhen Kharuzhy This file contains two types of quirks, both checking DMI for machine-specific strings and returning machine data for a matching entry. The first one, `cht_quirk`, is used to override the default entry for an existing ACPI codec node if the node's info is invalid. It returns either the matched machine data or the default entry if no match is found. The second one, `cht_yt3_quirk_cb`, is used for devices (originally the Lenovo Yoga Tab 3 Pro) without a valid codec DSDT entry. It is bound to the SST ACPI node and returns either the matched machine data or NULL if no match is found. To allow adding new machine entries to the second case and to use a single DMI match entry for both cases (for example, if two variants of one device exist: one with a valid ACPI entry and one without, like the Lenovo Yoga Book YB1-X91 and YB1-X90 - Windows and Android versions), reorganize these quirks functions to use the same approach: machine data is set in the matched dmi_system_id entry as driver_data field. Signed-off-by: Yauhen Kharuzhy <jekhor@gmail.com> --- sound/soc/intel/common/soc-acpi-intel-cht-match.c | 100 +++++++++------------- 1 file changed, 42 insertions(+), 58 deletions(-) diff --git a/sound/soc/intel/common/soc-acpi-intel-cht-match.c b/sound/soc/intel/common/soc-acpi-intel-cht-match.c index e4c3492a0c28..28f600171f9d 100644 --- a/sound/soc/intel/common/soc-acpi-intel-cht-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-cht-match.c @@ -9,47 +9,63 @@ #include <sound/soc-acpi.h> #include <sound/soc-acpi-intel-match.h> -static unsigned long cht_machine_id; - -#define CHT_SURFACE_MACH 1 +static struct snd_soc_acpi_mach cht_surface_mach = { + .id = "10EC5640", + .drv_name = "cht-bsw-rt5645", + .fw_filename = "intel/fw_sst_22a8.bin", + .board = "cht-bsw", + .sof_tplg_filename = "sof-cht-rt5645.tplg", +}; -static int cht_surface_quirk_cb(const struct dmi_system_id *id) -{ - cht_machine_id = CHT_SURFACE_MACH; - return 1; -} +static struct snd_soc_acpi_mach cht_lenovo_yoga_tab3_x90_mach = { + .id = "10WM5102", + .drv_name = "bytcr_wm5102", + .fw_filename = "intel/fw_sst_22a8.bin", + .board = "bytcr_wm5102", + .sof_tplg_filename = "sof-cht-wm5102.tplg", +}; static const struct dmi_system_id cht_table[] = { { - .callback = cht_surface_quirk_cb, + .driver_data = (void *)&cht_surface_mach, .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), DMI_MATCH(DMI_PRODUCT_NAME, "Surface 3"), }, }, + { + /* + * The Lenovo Yoga Tab 3 Pro YT3-X90, with Android factory OS + * has a buggy DSDT with the codec not being listed at all. + */ + .driver_data = (void *)&cht_lenovo_yoga_tab3_x90_mach, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), + DMI_MATCH(DMI_PRODUCT_VERSION, "Blade3-10A-001"), + }, + }, { } }; -static struct snd_soc_acpi_mach cht_surface_mach = { - .id = "10EC5640", - .drv_name = "cht-bsw-rt5645", - .fw_filename = "intel/fw_sst_22a8.bin", - .board = "cht-bsw", - .sof_tplg_filename = "sof-cht-rt5645.tplg", -}; - static struct snd_soc_acpi_mach *cht_quirk(void *arg) { struct snd_soc_acpi_mach *mach = arg; + const struct dmi_system_id *match; - dmi_check_system(cht_table); - - if (cht_machine_id == CHT_SURFACE_MACH) - return &cht_surface_mach; + match = dmi_first_match(cht_table); + if (match) + return (struct snd_soc_acpi_mach *)match->driver_data; else return mach; } +static struct snd_soc_acpi_mach *cht_quirk_strict(void *arg) +{ + struct snd_soc_acpi_mach *mach = cht_quirk(arg); + + return mach == arg ? NULL : mach; +} + /* * Some tablets with Android factory OS have buggy DSDTs with an ESSX8316 device * in the ACPI tables. While they are not using an ESS8316 codec. These DSDTs @@ -75,38 +91,6 @@ static struct snd_soc_acpi_mach *cht_ess8316_quirk(void *arg) return arg; } -/* - * The Lenovo Yoga Tab 3 Pro YT3-X90, with Android factory OS has a buggy DSDT - * with the coded not being listed at all. - */ -static const struct dmi_system_id lenovo_yoga_tab3_x90[] = { - { - /* Lenovo Yoga Tab 3 Pro YT3-X90, codec missing from DSDT */ - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), - DMI_MATCH(DMI_PRODUCT_VERSION, "Blade3-10A-001"), - }, - }, - { } -}; - -static struct snd_soc_acpi_mach cht_lenovo_yoga_tab3_x90_mach = { - .id = "10WM5102", - .drv_name = "bytcr_wm5102", - .fw_filename = "intel/fw_sst_22a8.bin", - .board = "bytcr_wm5102", - .sof_tplg_filename = "sof-cht-wm5102.tplg", -}; - -static struct snd_soc_acpi_mach *lenovo_yt3_x90_quirk(void *arg) -{ - if (dmi_check_system(lenovo_yoga_tab3_x90)) - return &cht_lenovo_yoga_tab3_x90_mach; - - /* Skip wildcard match snd_soc_acpi_intel_cherrytrail_machines[] entry */ - return NULL; -} - static const struct snd_soc_acpi_codecs rt5640_comp_ids = { .num_codecs = 2, .codecs = { "10EC5640", "10EC3276" }, @@ -208,14 +192,14 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_cherrytrail_machines[] = { .sof_tplg_filename = "sof-cht-src-50khz-pcm512x.tplg", }, /* - * Special case for the Lenovo Yoga Tab 3 Pro YT3-X90 where the DSDT - * misses the codec. Match on the SST id instead, lenovo_yt3_x90_quirk() - * will return a YT3 specific mach or NULL when called on other hw, - * skipping this entry. + * Special case for devices where the DSDT misses the codec. Match on + * the SST id instead, cht_quirk_nocodec() will return a + * device-specific mach for matched device or NULL when called on other + * hw, skipping this entry. */ { .id = "808622A8", - .machine_quirk = lenovo_yt3_x90_quirk, + .machine_quirk = cht_quirk_strict, }, #if IS_ENABLED(CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH) -- 2.53.0 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v3 1/3] ASoC: Intel: soc-acpi-cht: Unify device quirks 2026-06-10 23:51 ` [PATCH v3 1/3] ASoC: Intel: soc-acpi-cht: Unify device quirks Yauhen Kharuzhy @ 2026-06-11 8:47 ` Cezary Rojewski 2026-06-11 14:10 ` Mark Brown 1 sibling, 0 replies; 11+ messages in thread From: Cezary Rojewski @ 2026-06-11 8:47 UTC (permalink / raw) To: Yauhen Kharuzhy Cc: linux-sound, linux-kernel, Hans de Goede, Liam Girdwood, Peter Ujfalusi, Bard Liao, Ranjani Sridharan, Kai Vehmanen, Pierre-Louis Bossart, Mark Brown, Jaroslav Kysela, Takashi Iwai On 6/11/2026 1:51 AM, Yauhen Kharuzhy wrote: > This file contains two types of quirks, both checking DMI for > machine-specific strings and returning machine data for a matching entry. (...) > diff --git a/sound/soc/intel/common/soc-acpi-intel-cht-match.c b/sound/soc/intel/common/soc-acpi-intel-cht-match.c > index e4c3492a0c28..28f600171f9d 100644 > --- a/sound/soc/intel/common/soc-acpi-intel-cht-match.c > +++ b/sound/soc/intel/common/soc-acpi-intel-cht-match.c > @@ -9,47 +9,63 @@ > #include <sound/soc-acpi.h> > #include <sound/soc-acpi-intel-match.h> > > -static unsigned long cht_machine_id; > - > -#define CHT_SURFACE_MACH 1 > +static struct snd_soc_acpi_mach cht_surface_mach = { > + .id = "10EC5640", > + .drv_name = "cht-bsw-rt5645", > + .fw_filename = "intel/fw_sst_22a8.bin", > + .board = "cht-bsw", > + .sof_tplg_filename = "sof-cht-rt5645.tplg", Given all the relocations found in the patch, it's hard to assess the actual impact of it. Ideally there should be no need for the relocation at all. If you believe this has to be done, please split the change - first have a "preparation patch" that relocates stuff/does whatever is necessary with the existing tables (rt5645 and wm5102) and then have a follow up that carries "the impact". > +}; > > -static int cht_surface_quirk_cb(const struct dmi_system_id *id) > -{ > - cht_machine_id = CHT_SURFACE_MACH; > - return 1; > -} > +static struct snd_soc_acpi_mach cht_lenovo_yoga_tab3_x90_mach = { > + .id = "10WM5102", > + .drv_name = "bytcr_wm5102", > + .fw_filename = "intel/fw_sst_22a8.bin", > + .board = "bytcr_wm5102", > + .sof_tplg_filename = "sof-cht-wm5102.tplg", > +}; (...) > -static struct snd_soc_acpi_mach cht_surface_mach = { > - .id = "10EC5640", > - .drv_name = "cht-bsw-rt5645", > - .fw_filename = "intel/fw_sst_22a8.bin", > - .board = "cht-bsw", > - .sof_tplg_filename = "sof-cht-rt5645.tplg", > -}; (...) > -static struct snd_soc_acpi_mach cht_lenovo_yoga_tab3_x90_mach = { > - .id = "10WM5102", > - .drv_name = "bytcr_wm5102", > - .fw_filename = "intel/fw_sst_22a8.bin", > - .board = "bytcr_wm5102", > - .sof_tplg_filename = "sof-cht-wm5102.tplg", > -}; ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v3 1/3] ASoC: Intel: soc-acpi-cht: Unify device quirks 2026-06-10 23:51 ` [PATCH v3 1/3] ASoC: Intel: soc-acpi-cht: Unify device quirks Yauhen Kharuzhy 2026-06-11 8:47 ` Cezary Rojewski @ 2026-06-11 14:10 ` Mark Brown 2026-06-11 18:05 ` Yauhen Kharuzhy 1 sibling, 1 reply; 11+ messages in thread From: Mark Brown @ 2026-06-11 14:10 UTC (permalink / raw) To: Yauhen Kharuzhy Cc: Cezary Rojewski, Liam Girdwood, Peter Ujfalusi, Bard Liao, Ranjani Sridharan, Kai Vehmanen, Pierre-Louis Bossart, Jaroslav Kysela, Takashi Iwai, linux-sound, linux-kernel, Hans de Goede [-- Attachment #1: Type: text/plain, Size: 758 bytes --] On Thu, Jun 11, 2026 at 02:51:55AM +0300, Yauhen Kharuzhy wrote: > This file contains two types of quirks, both checking DMI for > machine-specific strings and returning machine data for a matching entry. You've not copied me on the rest of the series so I don't know what's going on with dependencies. When sending a patch series it is important to ensure that all the various maintainers understand what the relationship between the patches as the expecation is that there will be interdependencies. Either copy everyone on the whole series or at least copy them on the cover letter and explain what's going on. If there are no strong interdependencies then it's generally simplest to just send the patches separately to avoid any possible confusion. [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 488 bytes --] ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v3 1/3] ASoC: Intel: soc-acpi-cht: Unify device quirks 2026-06-11 14:10 ` Mark Brown @ 2026-06-11 18:05 ` Yauhen Kharuzhy 2026-06-11 18:12 ` Mark Brown 0 siblings, 1 reply; 11+ messages in thread From: Yauhen Kharuzhy @ 2026-06-11 18:05 UTC (permalink / raw) To: Mark Brown Cc: Cezary Rojewski, Liam Girdwood, Peter Ujfalusi, Bard Liao, Ranjani Sridharan, Kai Vehmanen, Pierre-Louis Bossart, Jaroslav Kysela, Takashi Iwai, linux-sound, linux-kernel, Hans de Goede On Thu, Jun 11, 2026 at 03:10:34PM +0100, Mark Brown wrote: > On Thu, Jun 11, 2026 at 02:51:55AM +0300, Yauhen Kharuzhy wrote: > > > This file contains two types of quirks, both checking DMI for > > machine-specific strings and returning machine data for a matching entry. > > You've not copied me on the rest of the series so I don't know what's > going on with dependencies. When sending a patch series it is important > to ensure that all the various maintainers understand what the > relationship between the patches as the expecation is that there will be > interdependencies. Either copy everyone on the whole series or at least > copy them on the cover letter and explain what's going on. If there are > no strong interdependencies then it's generally simplest to just send > the patches separately to avoid any possible confusion. Hi, Sorry, but your email is present in To: header of every patch in the series, could you explain what do you mean? -- Yauhen Kharuzhy ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v3 1/3] ASoC: Intel: soc-acpi-cht: Unify device quirks 2026-06-11 18:05 ` Yauhen Kharuzhy @ 2026-06-11 18:12 ` Mark Brown 0 siblings, 0 replies; 11+ messages in thread From: Mark Brown @ 2026-06-11 18:12 UTC (permalink / raw) To: Yauhen Kharuzhy Cc: Cezary Rojewski, Liam Girdwood, Peter Ujfalusi, Bard Liao, Ranjani Sridharan, Kai Vehmanen, Pierre-Louis Bossart, Jaroslav Kysela, Takashi Iwai, linux-sound, linux-kernel, Hans de Goede [-- Attachment #1: Type: text/plain, Size: 244 bytes --] On Thu, Jun 11, 2026 at 09:05:41PM +0300, Yauhen Kharuzhy wrote: > Sorry, but your email is present in To: header of every patch in the > series, could you explain what do you mean? There seems to have been some delay in delivering the rest. [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 488 bytes --] ^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v3 2/3] ASoC: Intel: soc-acpi-cht: Add Lenovo Yoga Book entries 2026-06-10 23:51 [PATCH v3 0/3] Add ASoC machine driver for Cherryview tablets with RT5677 Yauhen Kharuzhy 2026-06-10 23:51 ` [PATCH v3 1/3] ASoC: Intel: soc-acpi-cht: Unify device quirks Yauhen Kharuzhy @ 2026-06-10 23:51 ` Yauhen Kharuzhy 2026-06-11 8:50 ` Cezary Rojewski 2026-06-10 23:51 ` [PATCH v3 3/3] ASoC: Intel: Add cht_rt5677 driver Yauhen Kharuzhy 2 siblings, 1 reply; 11+ messages in thread From: Yauhen Kharuzhy @ 2026-06-10 23:51 UTC (permalink / raw) To: Cezary Rojewski, Liam Girdwood, Peter Ujfalusi, Bard Liao, Ranjani Sridharan, Kai Vehmanen, Pierre-Louis Bossart, Mark Brown, Jaroslav Kysela, Takashi Iwai Cc: linux-sound, linux-kernel, Hans de Goede, Yauhen Kharuzhy Lenovo Yoga Book YB1-X91 device uses a Cherry Trail SoC and has a valid ACPI DSDT entry for the RT5677 codec. This entry has some non-standard resource definitions, such as jack detection chip information, and hardware has some additional GPIO controls so use 'cht-yogabook' for the driver name instead of some default (like 'cht-bsw-rt5677'). Lenovo Yoga Book YB1-X90 device (Android version of the tablet) has the same hardware configuration but lacks a valid ACPI DSDT entry for the codec, so add DMI match data for it and use the same machine data as for YB1-X91. Signed-off-by: Yauhen Kharuzhy <jekhor@gmail.com> --- sound/soc/intel/common/soc-acpi-intel-cht-match.c | 40 +++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/sound/soc/intel/common/soc-acpi-intel-cht-match.c b/sound/soc/intel/common/soc-acpi-intel-cht-match.c index 28f600171f9d..5e8a1dc84ee1 100644 --- a/sound/soc/intel/common/soc-acpi-intel-cht-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-cht-match.c @@ -17,6 +17,14 @@ static struct snd_soc_acpi_mach cht_surface_mach = { .sof_tplg_filename = "sof-cht-rt5645.tplg", }; +static struct snd_soc_acpi_mach cht_yogabook_mach = { + .id = "10EC5677", + .drv_name = "cht-yogabook", + .fw_filename = "intel/fw_sst_22a8.bin", + .board = "cht-yogabook", + .sof_tplg_filename = "sof-cht-rt5677.tplg", +}; + static struct snd_soc_acpi_mach cht_lenovo_yoga_tab3_x90_mach = { .id = "10WM5102", .drv_name = "bytcr_wm5102", @@ -33,6 +41,24 @@ static const struct dmi_system_id cht_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Surface 3"), }, }, + { + .ident = "Lenovo Yoga Book YB1-X91", + .driver_data = (void *)&cht_yogabook_mach, + /* YB1-X91L/F */ + .matches = { + DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X91"), + } + }, + { + .ident = "Lenovo Yoga Book YB1-X90", + .driver_data = (void *)&cht_yogabook_mach, + /* YB1-X90L/F, codec is not listed in DSDT */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "CHERRYVIEW D1 PLATFORM"), + DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "YETI-11"), + } + }, { /* * The Lenovo Yoga Tab 3 Pro YT3-X90, with Android factory OS @@ -121,6 +147,20 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_cherrytrail_machines[] = { .board = "cht-bsw", .sof_tplg_filename = "sof-cht-rt5670.tplg", }, + /* + * The only known Cherry Trail device with RT5677 codec and 10EC677 + * DSTD entry is the Lenovo Yoga Book YB1-X91. It has a device-specific + * driver, so check DMI and use a machine quirk to override the default + * (non-existent) machine driver. + */ + { + .id = "10EC5677", + .drv_name = "cht-bsw-rt5677", + .fw_filename = "intel/fw_sst_22a8.bin", + .board = "cht-bsw", + .machine_quirk = cht_quirk, + .sof_tplg_filename = "sof-cht-rt5677.tplg", + }, { .comp_ids = &rt5645_comp_ids, .drv_name = "cht-bsw-rt5645", -- 2.53.0 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v3 2/3] ASoC: Intel: soc-acpi-cht: Add Lenovo Yoga Book entries 2026-06-10 23:51 ` [PATCH v3 2/3] ASoC: Intel: soc-acpi-cht: Add Lenovo Yoga Book entries Yauhen Kharuzhy @ 2026-06-11 8:50 ` Cezary Rojewski 0 siblings, 0 replies; 11+ messages in thread From: Cezary Rojewski @ 2026-06-11 8:50 UTC (permalink / raw) To: Yauhen Kharuzhy Cc: linux-sound, linux-kernel, Hans de Goede, Liam Girdwood, Peter Ujfalusi, Bard Liao, Ranjani Sridharan, Kai Vehmanen, Pierre-Louis Bossart, Mark Brown, Jaroslav Kysela, Takashi Iwai On 6/11/2026 1:51 AM, Yauhen Kharuzhy wrote: > Lenovo Yoga Book YB1-X91 device uses a Cherry Trail SoC and has a valid > ACPI DSDT entry for the RT5677 codec. This entry has some non-standard > resource definitions, such as jack detection chip information, and > hardware has some additional GPIO controls so use 'cht-yogabook' > for the driver name instead of some default (like 'cht-bsw-rt5677'). ... > diff --git a/sound/soc/intel/common/soc-acpi-intel-cht-match.c b/sound/soc/intel/common/soc-acpi-intel-cht-match.c > index 28f600171f9d..5e8a1dc84ee1 100644 > --- a/sound/soc/intel/common/soc-acpi-intel-cht-match.c > +++ b/sound/soc/intel/common/soc-acpi-intel-cht-match.c ... > @@ -121,6 +147,20 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_cherrytrail_machines[] = { > .board = "cht-bsw", > .sof_tplg_filename = "sof-cht-rt5670.tplg", > }, > + /* > + * The only known Cherry Trail device with RT5677 codec and 10EC677 > + * DSTD entry is the Lenovo Yoga Book YB1-X91. It has a device-specific > + * driver, so check DMI and use a machine quirk to override the default > + * (non-existent) machine driver. > + */ > + { > + .id = "10EC5677", > + .drv_name = "cht-bsw-rt5677", > + .fw_filename = "intel/fw_sst_22a8.bin", > + .board = "cht-bsw", > + .machine_quirk = cht_quirk, > + .sof_tplg_filename = "sof-cht-rt5677.tplg", The cover letter reads: v3: (...) - Remove support for SOF; and yet here you're assigning .sof_tplg_filename. > + }, > { > .comp_ids = &rt5645_comp_ids, > .drv_name = "cht-bsw-rt5645", > ^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v3 3/3] ASoC: Intel: Add cht_rt5677 driver 2026-06-10 23:51 [PATCH v3 0/3] Add ASoC machine driver for Cherryview tablets with RT5677 Yauhen Kharuzhy 2026-06-10 23:51 ` [PATCH v3 1/3] ASoC: Intel: soc-acpi-cht: Unify device quirks Yauhen Kharuzhy 2026-06-10 23:51 ` [PATCH v3 2/3] ASoC: Intel: soc-acpi-cht: Add Lenovo Yoga Book entries Yauhen Kharuzhy @ 2026-06-10 23:51 ` Yauhen Kharuzhy 2026-06-11 9:19 ` Cezary Rojewski 2 siblings, 1 reply; 11+ messages in thread From: Yauhen Kharuzhy @ 2026-06-10 23:51 UTC (permalink / raw) To: Cezary Rojewski, Liam Girdwood, Peter Ujfalusi, Bard Liao, Ranjani Sridharan, Kai Vehmanen, Pierre-Louis Bossart, Mark Brown, Jaroslav Kysela, Takashi Iwai Cc: linux-sound, linux-kernel, Hans de Goede, Yauhen Kharuzhy Add a new ASoC machine driver for Intel Cherry Trail platforms with rt5677 codec. It supports Lenovo Yoga Book tablets (YB1-X90F/L, YB1-X91F/L models) for now and can be extended for other platforms. This platform uses a Realtek ALC5677 codec accompanied by a TS3A227E jack configuration detection IC. The driver is based on the cht_bsw_rt5672.c mainline driver and the driver from the vendor's Android kernel [1]. There are no other known Cherry Trail platforms using an RT5677 codec, so some device-specific tricks are hardcoded, such as jack events and additional GPIOs controlling the speaker amplifier. [1] https://github.com/deadman96385/android_kernel_lenovo_yeti/blob/master/sound/soc/intel/board/cht_bl_dpcm_rt5677.c Signed-off-by: Yauhen Kharuzhy <jekhor@gmail.com> Assisted-by: Claude:claude-sonnet-4-6 --- sound/soc/intel/boards/Kconfig | 18 + sound/soc/intel/boards/Makefile | 2 + sound/soc/intel/boards/cht_rt5677.c | 564 ++++++++++++++++++++++ sound/soc/intel/common/soc-acpi-intel-cht-match.c | 29 +- 4 files changed, 590 insertions(+), 23 deletions(-) diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig index cddbd2aa424e..80633ca88612 100644 --- a/sound/soc/intel/boards/Kconfig +++ b/sound/soc/intel/boards/Kconfig @@ -198,6 +198,24 @@ config SND_SOC_INTEL_CHT_BSW_NAU8824_MACH Say Y or m if you have such a device. This is a recommended option. If unsure select "N". +config SND_SOC_INTEL_CHT_RT5677_MACH + tristate "Cherrytrail with RT5677 codec" + depends on I2C && ACPI + depends on X86_INTEL_LPSS || COMPILE_TEST + depends on GPIOLIB || COMPILE_TEST + select SND_SOC_ACPI + select SND_SOC_RT5677 + select SND_SOC_TS3A227E + help + This adds support for ASoC machine driver for Intel(R) Cherrytrail + platforms with RT5677 audio codec. + + The driver supports Lenovo Yoga Book tablets, models + YB1-X90F, YB1-X90L, YB1-X91F, YB1-X91L. The jack detection IC TS3A227E + is used. + Say Y or m if you have such a device. This is a recommended option. + If unsure select "N". + config SND_SOC_INTEL_BYT_CHT_CX2072X_MACH tristate "Baytrail & Cherrytrail with CX2072X codec" depends on I2C && ACPI diff --git a/sound/soc/intel/boards/Makefile b/sound/soc/intel/boards/Makefile index 25a1a9066cbf..c5fa9ddaf438 100644 --- a/sound/soc/intel/boards/Makefile +++ b/sound/soc/intel/boards/Makefile @@ -12,6 +12,7 @@ snd-soc-sst-cht-bsw-rt5672-y := cht_bsw_rt5672.o snd-soc-sst-cht-bsw-rt5645-y := cht_bsw_rt5645.o snd-soc-sst-cht-bsw-max98090_ti-y := cht_bsw_max98090_ti.o snd-soc-sst-cht-bsw-nau8824-y := cht_bsw_nau8824.o +snd-soc-sst-cht-rt5677-y := cht_rt5677.o snd-soc-sst-byt-cht-cx2072x-y := bytcht_cx2072x.o snd-soc-sst-byt-cht-da7213-y := bytcht_da7213.o snd-soc-sst-byt-cht-es8316-y := bytcht_es8316.o @@ -42,6 +43,7 @@ obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5651_MACH) += snd-soc-sst-bytcr-rt5651.o obj-$(CONFIG_SND_SOC_INTEL_BYTCR_WM5102_MACH) += snd-soc-sst-bytcr-wm5102.o obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH) += snd-soc-sst-cht-bsw-rt5672.o obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH) += snd-soc-sst-cht-bsw-rt5645.o +obj-$(CONFIG_SND_SOC_INTEL_CHT_RT5677_MACH) += snd-soc-sst-cht-rt5677.o obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH) += snd-soc-sst-cht-bsw-max98090_ti.o obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_NAU8824_MACH) += snd-soc-sst-cht-bsw-nau8824.o obj-$(CONFIG_SND_SOC_INTEL_BYT_CHT_CX2072X_MACH) += snd-soc-sst-byt-cht-cx2072x.o diff --git a/sound/soc/intel/boards/cht_rt5677.c b/sound/soc/intel/boards/cht_rt5677.c new file mode 100644 index 000000000000..d4dc31c13e31 --- /dev/null +++ b/sound/soc/intel/boards/cht_rt5677.c @@ -0,0 +1,564 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * cht_rt5677.c - ASoc Machine driver for Intel Cherrytrail platforms with an + * RT5677 audio codec. + * + * The driver supports Lenovo Yoga Book YB1-X90/X91 tablets and has some + * things hardcoded for these devices because there are no other known + * devices using such a configuration. + * + * Copyright (C) 2026 Yauhen Kharuzhy <jekhor@gmail.com> + * + * Based on the mainline cht_bsw_rt5672.c and on the cht_bl_dpcm_rt5677.c + * from Lenovo Android kernel. + */ + +#include <linux/cleanup.h> +#include <linux/clk.h> +#include <linux/dmi.h> +#include <linux/gpio/consumer.h> +#include <linux/gpio/machine.h> +#include <linux/i2c.h> +#include <linux/input.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <sound/jack.h> +#include <sound/pcm.h> +#include <sound/pcm_params.h> +#include <sound/soc-acpi.h> +#include <sound/soc.h> +#include "../../codecs/rt5677.h" +#include "../../codecs/ts3a227e.h" +#include "../atom/sst-atom-controls.h" + +#define RT5677_I2C_DEFAULT "i2c-rt5677" + +/* The platform clock #3 outputs 19.2Mhz clock to codec as I2S MCLK */ +#define CHT_PLAT_CLK_3_HZ 19200000 +#define CHT_CODEC_DAI "rt5677-aif1" + +struct cht_rt5677_private { + struct snd_soc_card card; + char codec_name[SND_ACPI_I2C_ID_LEN]; + struct snd_soc_jack jack; + struct clk *mclk; + struct gpio_desc *gpio_spk_en1; + struct gpio_desc *gpio_spk_en2; + struct gpio_desc *gpio_hp_en; +}; + +static int cht_rt5677_platform_clock_enable(struct snd_soc_card *card, + struct snd_soc_dai *codec_dai) +{ + struct cht_rt5677_private *ctx = snd_soc_card_get_drvdata(card); + int ret; + + ret = clk_prepare_enable(ctx->mclk); + if (ret < 0) { + dev_err(card->dev, "could not configure MCLK state: %d\n", ret); + return ret; + } + + /* set codec PLL source to the 19.2MHz platform clock (MCLK) */ + ret = snd_soc_dai_set_pll(codec_dai, 0, RT5677_PLL1_S_MCLK, + CHT_PLAT_CLK_3_HZ, 48000 * 512); + if (ret < 0) { + dev_err(card->dev, "can't set codec pll: %d\n", ret); + return ret; + } + + /* set codec sysclk source to PLL */ + ret = snd_soc_dai_set_sysclk(codec_dai, RT5677_SCLK_S_PLL1, + 48000 * 512, SND_SOC_CLOCK_IN); + if (ret < 0) { + dev_err(card->dev, "can't set codec sysclk: %d\n", ret); + return ret; + } + + return 0; +} + +static void cht_rt5677_platform_clock_disable(struct snd_soc_card *card, + struct snd_soc_dai *codec_dai) +{ + struct cht_rt5677_private *ctx = snd_soc_card_get_drvdata(card); + + /* Set codec sysclk source to its internal clock because codec + * PLL will be off when idle and MCLK will also be off by ACPI + * when codec is runtime suspended. Codec needs clock for jack + * detection and button press. + */ + snd_soc_dai_set_sysclk(codec_dai, RT5677_SCLK_S_RCCLK, + 48000 * 512, SND_SOC_CLOCK_IN); + + clk_disable_unprepare(ctx->mclk); +} + +static int cht_rt5677_platform_clock_control(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kctl, int event) +{ + struct snd_soc_card *card = snd_soc_dapm_to_card(w->dapm); + struct snd_soc_dai *codec_dai; + + codec_dai = snd_soc_card_get_codec_dai(card, CHT_CODEC_DAI); + if (!codec_dai) { + dev_err(card->dev, + "Codec dai not found; Unable to set platform clock\n"); + return -EIO; + } + + if (SND_SOC_DAPM_EVENT_ON(event)) + return cht_rt5677_platform_clock_enable(card, codec_dai); + + cht_rt5677_platform_clock_disable(card, codec_dai); + + return 0; +} + +static int cht_rt5677_hp_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kctl, int event) +{ + struct snd_soc_card *card = snd_soc_dapm_to_card(w->dapm); + struct cht_rt5677_private *ctx = snd_soc_card_get_drvdata(card); + + gpiod_set_value_cansleep(ctx->gpio_hp_en, SND_SOC_DAPM_EVENT_ON(event)); + + return 0; +} + +static int cht_rt5677_spk_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kctl, int event) +{ + struct snd_soc_card *card = snd_soc_dapm_to_card(w->dapm); + struct cht_rt5677_private *ctx = snd_soc_card_get_drvdata(card); + + gpiod_set_value_cansleep(ctx->gpio_spk_en1, + SND_SOC_DAPM_EVENT_ON(event)); + gpiod_set_value_cansleep(ctx->gpio_spk_en2, + SND_SOC_DAPM_EVENT_ON(event)); + + return 0; +} + +static const struct snd_soc_dapm_widget cht_rt5677_dapm_widgets[] = { + SND_SOC_DAPM_HP("Headphone", cht_rt5677_hp_event), + SND_SOC_DAPM_MIC("Headset Mic", NULL), + SND_SOC_DAPM_MIC("Int Mic", NULL), + SND_SOC_DAPM_SPK("Speaker", cht_rt5677_spk_event), + SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, + cht_rt5677_platform_clock_control, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), +}; + +static const struct snd_soc_dapm_route cht_rt5677_audio_map[] = { + {"IN1P", NULL, "Headset Mic"}, + {"IN1N", NULL, "Headset Mic"}, + {"DMIC L1", NULL, "Int Mic"}, + {"DMIC R1", NULL, "Int Mic"}, + {"Headphone", NULL, "LOUT1"}, + {"Headphone", NULL, "LOUT2"}, + {"Speaker", NULL, "LOUT1"}, + {"Speaker", NULL, "LOUT2"}, + + {"AIF1 Playback", NULL, "ssp2 Tx"}, + {"ssp2 Tx", NULL, "codec_out0"}, + {"ssp2 Tx", NULL, "codec_out1"}, + {"codec_in0", NULL, "ssp2 Rx"}, + {"codec_in1", NULL, "ssp2 Rx"}, + {"ssp2 Rx", NULL, "AIF1 Capture"}, + {"Headphone", NULL, "Platform Clock"}, + {"Speaker", NULL, "Platform Clock"}, + {"Headset Mic", NULL, "Platform Clock"}, + {"Int Mic", NULL, "Platform Clock"}, +}; + +static const struct snd_kcontrol_new cht_rt5677_controls[] = { + SOC_DAPM_PIN_SWITCH("Headphone"), + SOC_DAPM_PIN_SWITCH("Headset Mic"), + SOC_DAPM_PIN_SWITCH("Int Mic"), + SOC_DAPM_PIN_SWITCH("Speaker"), +}; + +static int cht_rt5677_aif1_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); + int ret; + + /* set codec PLL source to the 19.2MHz platform clock (MCLK) */ + ret = snd_soc_dai_set_pll(codec_dai, 0, RT5677_PLL1_S_MCLK, + CHT_PLAT_CLK_3_HZ, params_rate(params) * 512); + if (ret < 0) { + dev_err(rtd->dev, "can't set codec pll: %d\n", ret); + return ret; + } + + /* set codec sysclk source to PLL */ + ret = snd_soc_dai_set_sysclk(codec_dai, RT5677_SCLK_S_PLL1, + params_rate(params) * 512, + SND_SOC_CLOCK_IN); + if (ret < 0) { + dev_err(rtd->dev, "can't set codec sysclk: %d\n", ret); + return ret; + } + + /* Default mode for SSP configuration is TDM 4 slot */ + ret = snd_soc_dai_set_fmt(codec_dai, + SND_SOC_DAIFMT_DSP_B | + SND_SOC_DAIFMT_IB_NF | + SND_SOC_DAIFMT_CBC_CFC); + if (ret < 0) { + dev_err(codec_dai->dev, "can't set format to TDM %d\n", ret); + return ret; + } + + /* TDM 4 slots 24 bit, set Rx & Tx bitmask to 4 active slots */ + ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xF, 0xF, 4, 25); + if (ret < 0) { + dev_err(rtd->dev, "can't set codec TDM slot %d\n", ret); + return ret; + } + + return 0; +} + +static int cht_rt5677_codec_init(struct snd_soc_pcm_runtime *runtime) +{ + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(runtime, 0); + struct snd_soc_component *component = codec_dai->component; + struct cht_rt5677_private *ctx = snd_soc_card_get_drvdata(runtime->card); + int ret = 0; + + /* Enable codec ASRC function for Stereo DAC/Stereo1 ADC/DMIC/I2S1. + * The ASRC clock source is clk_i2s1_asrc. + */ + rt5677_sel_asrc_clk_src(component, RT5677_DA_STEREO_FILTER | + RT5677_AD_STEREO1_FILTER | RT5677_I2S1_SOURCE, + RT5677_CLK_SEL_I2S1_ASRC); + /* Enable codec ASRC function for Mono ADC L. + * The ASRC clock source is clk_sys2_asrc. + */ + rt5677_sel_asrc_clk_src(component, RT5677_AD_MONO_L_FILTER, + RT5677_CLK_SEL_SYS2); + + /* + * The firmware might enable the clock at + * boot (this information may or may not + * be reflected in the enable clock register). + * To change the rate we must disable the clock + * first to cover these cases. Due to common + * clock framework restrictions that do not allow + * to disable a clock that has not been enabled, + * we need to enable the clock first. + */ + ret = clk_prepare_enable(ctx->mclk); + if (!ret) + clk_disable_unprepare(ctx->mclk); + + ret = clk_set_rate(ctx->mclk, CHT_PLAT_CLK_3_HZ); + if (ret) { + dev_err(runtime->dev, "unable to set MCLK rate\n"); + return ret; + } + + return 0; +} + +static int cht_rt5677_codec_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + + /* The DSP will convert the FE rate to 48k, stereo, 24bits */ + rate->min = rate->max = 48000; + channels->min = channels->max = 2; + + /* set SSP2 to 24-bit */ + params_set_format(params, SNDRV_PCM_FORMAT_S24_LE); + + return 0; +} + +static struct snd_soc_jack_pin cht_rt5677_jack_pins[] = { + { + .pin = "Headphone", + .mask = SND_JACK_HEADPHONE, + }, + { + .pin = "Headset Mic", + .mask = SND_JACK_MICROPHONE, + }, +}; + +static int cht_rt5677_headset_init(struct snd_soc_component *component) +{ + struct snd_soc_card *card = component->card; + struct cht_rt5677_private *ctx = snd_soc_card_get_drvdata(card); + struct snd_soc_jack *jack = &ctx->jack; + int jack_type; + int ret; + + /* + * TS3A227E supports 4 butons headset detection + * KEY_MEDIA + * KEY_VOICECOMMAND + * KEY_VOLUMEUP + * KEY_VOLUMEDOWN + */ + jack_type = SND_JACK_HEADPHONE | SND_JACK_MICROPHONE | + SND_JACK_BTN_0 | SND_JACK_BTN_1 | + SND_JACK_BTN_2 | SND_JACK_BTN_3; + + ret = snd_soc_card_jack_new_pins(card, "Headset Jack", + jack_type, jack, + cht_rt5677_jack_pins, + ARRAY_SIZE(cht_rt5677_jack_pins)); + if (ret) { + dev_err(card->dev, "Headset Jack creation failed %d\n", ret); + return ret; + } + + return ts3a227e_enable_jack_detect(component, jack); +} + +static int cht_rt5677_aif1_startup(struct snd_pcm_substream *substream) +{ + return snd_pcm_hw_constraint_single(substream->runtime, + SNDRV_PCM_HW_PARAM_RATE, 48000); +} + +static const struct snd_soc_ops cht_rt5677_aif1_ops = { + .startup = cht_rt5677_aif1_startup, +}; + +static const struct snd_soc_ops cht_rt5677_be_ssp2_ops = { + .hw_params = cht_rt5677_aif1_hw_params, +}; + +static struct snd_soc_aux_dev cht_rt5677_headset_dev = { + .dlc = COMP_AUX("i2c-ts3a227e"), + .init = cht_rt5677_headset_init, +}; + +SND_SOC_DAILINK_DEF(dummy, + DAILINK_COMP_ARRAY(COMP_DUMMY())); + +SND_SOC_DAILINK_DEF(media, + DAILINK_COMP_ARRAY(COMP_CPU("media-cpu-dai"))); + +SND_SOC_DAILINK_DEF(deepbuffer, + DAILINK_COMP_ARRAY(COMP_CPU("deepbuffer-cpu-dai"))); + +SND_SOC_DAILINK_DEF(ssp2_port, + DAILINK_COMP_ARRAY(COMP_CPU("ssp2-port"))); +SND_SOC_DAILINK_DEF(ssp2_codec, + DAILINK_COMP_ARRAY(COMP_CODEC(RT5677_I2C_DEFAULT, + "rt5677-aif1"))); + +SND_SOC_DAILINK_DEF(platform, + DAILINK_COMP_ARRAY(COMP_PLATFORM("sst-mfld-platform"))); + +static struct snd_soc_dai_link cht_rt5677_dailink[] = { + /* Front End DAI links */ + [MERR_DPCM_AUDIO] = { + .name = "Audio Port", + .stream_name = "Audio", + .nonatomic = true, + .dynamic = 1, + .ops = &cht_rt5677_aif1_ops, + SND_SOC_DAILINK_REG(media, dummy, platform), + }, + [MERR_DPCM_DEEP_BUFFER] = { + .name = "Deep-Buffer Audio Port", + .stream_name = "Deep-Buffer Audio", + .nonatomic = true, + .dynamic = 1, + .playback_only = 1, + .ops = &cht_rt5677_aif1_ops, + SND_SOC_DAILINK_REG(deepbuffer, dummy, platform), + }, + + /* Back End DAI links */ + { + /* SSP2 - Codec */ + .name = "SSP2-Codec", + .id = 0, + .no_pcm = 1, + .nonatomic = true, + .init = cht_rt5677_codec_init, + .be_hw_params_fixup = cht_rt5677_codec_fixup, + .ops = &cht_rt5677_be_ssp2_ops, + SND_SOC_DAILINK_REG(ssp2_port, ssp2_codec, platform), + }, +}; + +static const struct acpi_gpio_params speaker_enable_gpio = { 2, 0, false }; +static const struct acpi_gpio_mapping cht_rt5677_gpios[] = { + { "speaker-enable-gpios", &speaker_enable_gpio, 1 }, + { NULL } +}; + +static int snd_cht_rt5677_probe(struct platform_device *pdev) +{ + struct snd_soc_acpi_mach *mach = dev_get_platdata(&pdev->dev); + struct acpi_device *adev; + struct cht_rt5677_private *ctx; + struct snd_soc_card *card; + const char *platform_name; + int ret = 0; + int i; + + ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); + if (!ctx) + return -ENOMEM; + + card = &ctx->card; + card->dev = &pdev->dev; + card->owner = THIS_MODULE; + card->name = "cht-rt5677"; + card->dai_link = cht_rt5677_dailink, + card->num_links = ARRAY_SIZE(cht_rt5677_dailink), + card->aux_dev = &cht_rt5677_headset_dev, + card->num_aux_devs = 1, + card->dapm_widgets = cht_rt5677_dapm_widgets, + card->num_dapm_widgets = ARRAY_SIZE(cht_rt5677_dapm_widgets), + card->dapm_routes = cht_rt5677_audio_map, + card->num_dapm_routes = ARRAY_SIZE(cht_rt5677_audio_map), + card->controls = cht_rt5677_controls, + card->num_controls = ARRAY_SIZE(cht_rt5677_controls), + + strscpy(ctx->codec_name, RT5677_I2C_DEFAULT); + + /* fixup codec name based on HID if ACPI node is present */ + adev = acpi_dev_get_first_match_dev(mach->id, NULL, -1); + if (adev) { + snprintf(ctx->codec_name, sizeof(ctx->codec_name), + "i2c-%s", acpi_dev_name(adev)); + + acpi_dev_put(adev); + for (i = 0; i < ARRAY_SIZE(cht_rt5677_dailink); i++) { + if (cht_rt5677_dailink[i].codecs->name && + !strcmp(cht_rt5677_dailink[i].codecs->name, + RT5677_I2C_DEFAULT)) { + cht_rt5677_dailink[i].codecs->name = ctx->codec_name; + break; + } + } + } + + struct device *codec_dev __free(put_device) = + bus_find_device_by_name(&i2c_bus_type, NULL, ctx->codec_name); + + if (!codec_dev) + return -EPROBE_DEFER; + + if (adev) { + ret = devm_acpi_dev_add_driver_gpios(codec_dev, + cht_rt5677_gpios); + if (ret) + dev_warn(&pdev->dev, + "Unable to add GPIO mapping table: %d\n", + ret); + } + + ctx->gpio_spk_en1 = gpiod_get(codec_dev, "speaker-enable", GPIOD_OUT_LOW); + if (IS_ERR(ctx->gpio_spk_en1)) { + ret = PTR_ERR(ctx->gpio_spk_en1); + return dev_err_probe(&pdev->dev, ret, "getting speaker enable GPIO\n"); + } + + ctx->gpio_spk_en2 = gpiod_get(codec_dev, "speaker-enable2", GPIOD_OUT_LOW); + if (IS_ERR(ctx->gpio_spk_en2)) { + ret = PTR_ERR(ctx->gpio_spk_en2); + dev_err_probe(codec_dev, ret, "getting speaker enable 2 GPIO\n"); + goto out_put_spken_gpio; + } + + ctx->gpio_hp_en = gpiod_get(codec_dev, "headphone-enable", GPIOD_OUT_LOW); + if (IS_ERR(ctx->gpio_hp_en)) { + ret = PTR_ERR(ctx->gpio_hp_en); + dev_err_probe(codec_dev, ret, "getting headphone enable GPIO\n"); + goto out_put_spken2_gpio; + } + + /* override platform name, if required */ + platform_name = mach->mach_params.platform; + + ret = snd_soc_fixup_dai_links_platform_name(card, platform_name); + if (ret) { + dev_err_probe(&pdev->dev, ret, "fixing up dai links platform name\n"); + goto out_put_hpen_gpio; + } + + ctx->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3"); + if (IS_ERR(ctx->mclk)) { + ret = PTR_ERR(ctx->mclk); + dev_err_probe(&pdev->dev, ret, "getting MCLK from pmc_plt_clk_3\n"); + goto out_put_hpen_gpio; + } + + snd_soc_card_set_drvdata(card, ctx); + + /* register the soc card */ + ret = devm_snd_soc_register_card(&pdev->dev, card); + if (ret) { + dev_err_probe(&pdev->dev, ret, "registering card\n"); + goto out_put_hpen_gpio; + } + + return 0; + +out_put_hpen_gpio: + gpiod_put(ctx->gpio_hp_en); +out_put_spken2_gpio: + gpiod_put(ctx->gpio_spk_en2); +out_put_spken_gpio: + gpiod_put(ctx->gpio_spk_en1); + + return ret; +} + +static void snd_cht_rt5677_remove(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct cht_rt5677_private *ctx = snd_soc_card_get_drvdata(card); + int i; + + /* + * Reset the codec name in the global dailink array back to the default + * to avoid a use-after-free on driver rebind (unbind/bind): + * ctx->codec_name is about to be freed together with ctx (devm), but + * cht_rt5677_dailink[] is a static global that persists across binds. + */ + for (i = 0; i < ARRAY_SIZE(cht_rt5677_dailink); i++) { + if (cht_rt5677_dailink[i].codecs->name == ctx->codec_name) { + cht_rt5677_dailink[i].codecs->name = RT5677_I2C_DEFAULT; + break; + } + } + + gpiod_put(ctx->gpio_hp_en); + gpiod_put(ctx->gpio_spk_en2); + gpiod_put(ctx->gpio_spk_en1); +} + +static struct platform_driver snd_cht_rt5677_driver = { + .driver = { + .name = "cht-rt5677", + .pm = &snd_soc_pm_ops, + }, + .probe = snd_cht_rt5677_probe, + .remove = snd_cht_rt5677_remove, +}; + +module_platform_driver(snd_cht_rt5677_driver); + +MODULE_DESCRIPTION("ASoC Intel Cherrytrail with RT5677 machine driver"); +MODULE_AUTHOR("Yauhen Kharuzhy"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:cht-rt5677"); diff --git a/sound/soc/intel/common/soc-acpi-intel-cht-match.c b/sound/soc/intel/common/soc-acpi-intel-cht-match.c index 5e8a1dc84ee1..c719c3ec8314 100644 --- a/sound/soc/intel/common/soc-acpi-intel-cht-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-cht-match.c @@ -17,12 +17,11 @@ static struct snd_soc_acpi_mach cht_surface_mach = { .sof_tplg_filename = "sof-cht-rt5645.tplg", }; -static struct snd_soc_acpi_mach cht_yogabook_mach = { +static struct snd_soc_acpi_mach cht_rt5677_mach = { .id = "10EC5677", - .drv_name = "cht-yogabook", + .drv_name = "cht-rt5677", .fw_filename = "intel/fw_sst_22a8.bin", - .board = "cht-yogabook", - .sof_tplg_filename = "sof-cht-rt5677.tplg", + .board = "cht_rt5677", }; static struct snd_soc_acpi_mach cht_lenovo_yoga_tab3_x90_mach = { @@ -41,17 +40,9 @@ static const struct dmi_system_id cht_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Surface 3"), }, }, - { - .ident = "Lenovo Yoga Book YB1-X91", - .driver_data = (void *)&cht_yogabook_mach, - /* YB1-X91L/F */ - .matches = { - DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X91"), - } - }, { .ident = "Lenovo Yoga Book YB1-X90", - .driver_data = (void *)&cht_yogabook_mach, + .driver_data = (void *)&cht_rt5677_mach, /* YB1-X90L/F, codec is not listed in DSDT */ .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), @@ -147,19 +138,11 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_cherrytrail_machines[] = { .board = "cht-bsw", .sof_tplg_filename = "sof-cht-rt5670.tplg", }, - /* - * The only known Cherry Trail device with RT5677 codec and 10EC677 - * DSTD entry is the Lenovo Yoga Book YB1-X91. It has a device-specific - * driver, so check DMI and use a machine quirk to override the default - * (non-existent) machine driver. - */ { .id = "10EC5677", - .drv_name = "cht-bsw-rt5677", + .drv_name = "cht-rt5677", .fw_filename = "intel/fw_sst_22a8.bin", - .board = "cht-bsw", - .machine_quirk = cht_quirk, - .sof_tplg_filename = "sof-cht-rt5677.tplg", + .board = "cht_rt5677", }, { .comp_ids = &rt5645_comp_ids, -- 2.53.0 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v3 3/3] ASoC: Intel: Add cht_rt5677 driver 2026-06-10 23:51 ` [PATCH v3 3/3] ASoC: Intel: Add cht_rt5677 driver Yauhen Kharuzhy @ 2026-06-11 9:19 ` Cezary Rojewski 2026-06-11 21:53 ` Yauhen Kharuzhy 0 siblings, 1 reply; 11+ messages in thread From: Cezary Rojewski @ 2026-06-11 9:19 UTC (permalink / raw) To: Yauhen Kharuzhy Cc: linux-sound, linux-kernel, Hans de Goede, Liam Girdwood, Peter Ujfalusi, Bard Liao, Ranjani Sridharan, Kai Vehmanen, Pierre-Louis Bossart, Mark Brown, Jaroslav Kysela, Takashi Iwai On 6/11/2026 1:51 AM, Yauhen Kharuzhy wrote: > Add a new ASoC machine driver for Intel Cherry Trail platforms with > rt5677 codec. ... > +struct cht_rt5677_private { > + struct snd_soc_card card; > + char codec_name[SND_ACPI_I2C_ID_LEN]; > + struct snd_soc_jack jack; I'm strongly against any private context encompassing card and jack as fields (sick!). The design looks off - it's very unlikely you need to store the card (even as pointer) at all. All the APIs found below either hand you *card on the platter or provide means to do so e.g.: component->card. Retrieving private context from the card is a formality. > + struct clk *mclk; > + struct gpio_desc *gpio_spk_en1; > + struct gpio_desc *gpio_spk_en2; > + struct gpio_desc *gpio_hp_en; > +}; > + > +static int cht_rt5677_platform_clock_enable(struct snd_soc_card *card, > + struct snd_soc_dai *codec_dai) > +{ > + struct cht_rt5677_private *ctx = snd_soc_card_get_drvdata(card); > + int ret; > + > + ret = clk_prepare_enable(ctx->mclk); (save: enable succeeds) > + if (ret < 0) { > + dev_err(card->dev, "could not configure MCLK state: %d\n", ret); > + return ret; > + } > + > + /* set codec PLL source to the 19.2MHz platform clock (MCLK) */ > + ret = snd_soc_dai_set_pll(codec_dai, 0, RT5677_PLL1_S_MCLK, > + CHT_PLAT_CLK_3_HZ, 48000 * 512); > + if (ret < 0) { > + dev_err(card->dev, "can't set codec pll: %d\n", ret); > + return ret; (save: set_pll fails) Result: clk is still running despite cht_rt5677_platform_clock_enable() failing. > + } > + > + /* set codec sysclk source to PLL */ > + ret = snd_soc_dai_set_sysclk(codec_dai, RT5677_SCLK_S_PLL1, > + 48000 * 512, SND_SOC_CLOCK_IN); > + if (ret < 0) { > + dev_err(card->dev, "can't set codec sysclk: %d\n", ret); > + return ret; And the story repeats itself here too. > + } > + > + return 0; > +} ... > +static int cht_rt5677_codec_init(struct snd_soc_pcm_runtime *runtime) > +{ > + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(runtime, 0); > + struct snd_soc_component *component = codec_dai->component; > + struct cht_rt5677_private *ctx = snd_soc_card_get_drvdata(runtime->card); > + int ret = 0; > + > + /* Enable codec ASRC function for Stereo DAC/Stereo1 ADC/DMIC/I2S1. > + * The ASRC clock source is clk_i2s1_asrc. > + */ Explain _why_, don't just repeat the what's clearly visible in the parameter list. Otherwise, just drop the comment. > + rt5677_sel_asrc_clk_src(component, RT5677_DA_STEREO_FILTER | > + RT5677_AD_STEREO1_FILTER | RT5677_I2S1_SOURCE, > + RT5677_CLK_SEL_I2S1_ASRC); > + /* Enable codec ASRC function for Mono ADC L. > + * The ASRC clock source is clk_sys2_asrc. > + */ Ditto. > + rt5677_sel_asrc_clk_src(component, RT5677_AD_MONO_L_FILTER, > + RT5677_CLK_SEL_SYS2); > + > + /* > + * The firmware might enable the clock at > + * boot (this information may or may not > + * be reflected in the enable clock register). > + * To change the rate we must disable the clock > + * first to cover these cases. Due to common > + * clock framework restrictions that do not allow > + * to disable a clock that has not been enabled, > + * we need to enable the clock first. > + */ > + ret = clk_prepare_enable(ctx->mclk); > + if (!ret) > + clk_disable_unprepare(ctx->mclk); > + > + ret = clk_set_rate(ctx->mclk, CHT_PLAT_CLK_3_HZ); > + if (ret) { > + dev_err(runtime->dev, "unable to set MCLK rate\n"); > + return ret; > + } > + > + return 0; > +} ... > +static const struct acpi_gpio_params speaker_enable_gpio = { 2, 0, false }; > +static const struct acpi_gpio_mapping cht_rt5677_gpios[] = { > + { "speaker-enable-gpios", &speaker_enable_gpio, 1 }, > + { NULL } Drop the NULL. > +}; > + > +static int snd_cht_rt5677_probe(struct platform_device *pdev) ... > + ctx->gpio_hp_en = gpiod_get(codec_dev, "headphone-enable", GPIOD_OUT_LOW); > + if (IS_ERR(ctx->gpio_hp_en)) { > + ret = PTR_ERR(ctx->gpio_hp_en); > + dev_err_probe(codec_dev, ret, "getting headphone enable GPIO\n"); > + goto out_put_spken2_gpio; > + } > + > + /* override platform name, if required */ The comment is redundant, explains nothing, drop it. > + platform_name = mach->mach_params.platform; > + > + ret = snd_soc_fixup_dai_links_platform_name(card, platform_name); > + if (ret) { > + dev_err_probe(&pdev->dev, ret, "fixing up dai links platform name\n"); > + goto out_put_hpen_gpio; > + } > + > + ctx->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3"); > + if (IS_ERR(ctx->mclk)) { > + ret = PTR_ERR(ctx->mclk); > + dev_err_probe(&pdev->dev, ret, "getting MCLK from pmc_plt_clk_3\n"); > + goto out_put_hpen_gpio; > + } > + > + snd_soc_card_set_drvdata(card, ctx); > + > + /* register the soc card */ Ditto. The funtion's name says it all. > + ret = devm_snd_soc_register_card(&pdev->dev, card); > + if (ret) { > + dev_err_probe(&pdev->dev, ret, "registering card\n"); > + goto out_put_hpen_gpio; > + } > + > + return 0; > + > +out_put_hpen_gpio: > + gpiod_put(ctx->gpio_hp_en); > +out_put_spken2_gpio: > + gpiod_put(ctx->gpio_spk_en2); > +out_put_spken_gpio: > + gpiod_put(ctx->gpio_spk_en1); > + > + return ret; > +} > + > +static void snd_cht_rt5677_remove(struct platform_device *pdev) > +{ > + struct snd_soc_card *card = platform_get_drvdata(pdev); > + struct cht_rt5677_private *ctx = snd_soc_card_get_drvdata(card); > + int i; > + > + /* > + * Reset the codec name in the global dailink array back to the default > + * to avoid a use-after-free on driver rebind (unbind/bind): > + * ctx->codec_name is about to be freed together with ctx (devm), but > + * cht_rt5677_dailink[] is a static global that persists across binds. > + */ All of this looks like a hack and brings me closer to simply stating: NAK as I do not believe the patch has been thoroughly tested if such hacks exist. remove() procedure should not care about codecs->name. > + for (i = 0; i < ARRAY_SIZE(cht_rt5677_dailink); i++) { > + if (cht_rt5677_dailink[i].codecs->name == ctx->codec_name) { > + cht_rt5677_dailink[i].codecs->name = RT5677_I2C_DEFAULT; > + break; > + } > + } > + > + gpiod_put(ctx->gpio_hp_en); > + gpiod_put(ctx->gpio_spk_en2); > + gpiod_put(ctx->gpio_spk_en1); > +} ... > diff --git a/sound/soc/intel/common/soc-acpi-intel-cht-match.c b/sound/soc/intel/common/soc-acpi-intel-cht-match.c > index 5e8a1dc84ee1..c719c3ec8314 100644 > --- a/sound/soc/intel/common/soc-acpi-intel-cht-match.c > +++ b/sound/soc/intel/common/soc-acpi-intel-cht-match.c > @@ -17,12 +17,11 @@ static struct snd_soc_acpi_mach cht_surface_mach = { > .sof_tplg_filename = "sof-cht-rt5645.tplg", > }; > > -static struct snd_soc_acpi_mach cht_yogabook_mach = { > +static struct snd_soc_acpi_mach cht_rt5677_mach = { > .id = "10EC5677", > - .drv_name = "cht-yogabook", > + .drv_name = "cht-rt5677", > .fw_filename = "intel/fw_sst_22a8.bin", > - .board = "cht-yogabook", > - .sof_tplg_filename = "sof-cht-rt5677.tplg", > + .board = "cht_rt5677", > }; > > static struct snd_soc_acpi_mach cht_lenovo_yoga_tab3_x90_mach = { > @@ -41,17 +40,9 @@ static const struct dmi_system_id cht_table[] = { > DMI_MATCH(DMI_PRODUCT_NAME, "Surface 3"), > }, > }, > - { > - .ident = "Lenovo Yoga Book YB1-X91", > - .driver_data = (void *)&cht_yogabook_mach, > - /* YB1-X91L/F */ > - .matches = { > - DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X91"), > - } > - }, > { > .ident = "Lenovo Yoga Book YB1-X90", > - .driver_data = (void *)&cht_yogabook_mach, > + .driver_data = (void *)&cht_rt5677_mach, > /* YB1-X90L/F, codec is not listed in DSDT */ > .matches = { > DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), > @@ -147,19 +138,11 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_cherrytrail_machines[] = { > .board = "cht-bsw", > .sof_tplg_filename = "sof-cht-rt5670.tplg", > }, > - /* > - * The only known Cherry Trail device with RT5677 codec and 10EC677 > - * DSTD entry is the Lenovo Yoga Book YB1-X91. It has a device-specific > - * driver, so check DMI and use a machine quirk to override the default > - * (non-existent) machine driver. > - */ You are removing and editing (the below table) code you've just added with 2/3. This looks very bad. > { > .id = "10EC5677", > - .drv_name = "cht-bsw-rt5677", > + .drv_name = "cht-rt5677", > .fw_filename = "intel/fw_sst_22a8.bin", > - .board = "cht-bsw", > - .machine_quirk = cht_quirk, > - .sof_tplg_filename = "sof-cht-rt5677.tplg", > + .board = "cht_rt5677", > }, > { > .comp_ids = &rt5645_comp_ids, > ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v3 3/3] ASoC: Intel: Add cht_rt5677 driver 2026-06-11 9:19 ` Cezary Rojewski @ 2026-06-11 21:53 ` Yauhen Kharuzhy 0 siblings, 0 replies; 11+ messages in thread From: Yauhen Kharuzhy @ 2026-06-11 21:53 UTC (permalink / raw) To: Cezary Rojewski Cc: linux-sound, linux-kernel, Hans de Goede, Liam Girdwood, Peter Ujfalusi, Bard Liao, Ranjani Sridharan, Kai Vehmanen, Pierre-Louis Bossart, Mark Brown, Jaroslav Kysela, Takashi Iwai On Thu, Jun 11, 2026 at 11:19:10AM +0200, Cezary Rojewski wrote: > On 6/11/2026 1:51 AM, Yauhen Kharuzhy wrote: > > Add a new ASoC machine driver for Intel Cherry Trail platforms with > > rt5677 codec. > > ... > > +static void snd_cht_rt5677_remove(struct platform_device *pdev) > > +{ > > + struct snd_soc_card *card = platform_get_drvdata(pdev); > > + struct cht_rt5677_private *ctx = snd_soc_card_get_drvdata(card); > > + int i; > > + > > + /* > > + * Reset the codec name in the global dailink array back to the default > > + * to avoid a use-after-free on driver rebind (unbind/bind): > > + * ctx->codec_name is about to be freed together with ctx (devm), but > > + * cht_rt5677_dailink[] is a static global that persists across binds. > > + */ > > All of this looks like a hack and brings me closer to simply stating: > > NAK > > as I do not believe the patch has been thoroughly tested if such hacks > exist. remove() procedure should not care about codecs->name. I agree but it was a simplest way to fix a possible use-after-free in probe(): ctx = kzalloc(); ... if (cht_rt5677_dailink[i].codecs->name && !strcmp(cht_rt5677_dailink[i].codecs->name, RT5677_I2C_DEFAULT)) cht_rt5677_dailink[i].codecs->name = ctx->codec_name; So, if ctx will be freed (after remove()) and probe() will be called again, then cht_rt5677_dailink[i].codecs->name will be invalid. Now I have checked how this issue is resolved in similar drivers. For example, cht_bsw_rt5672.c has the same pattern with potential use-after-free. cht_bsw_rt5645.c uses a statically allocated buffer to store the name instead of field inside a dynamically allocated context. Maybe a such approach with static buffer would be an acceptable compromise. > > > + for (i = 0; i < ARRAY_SIZE(cht_rt5677_dailink); i++) { > > + if (cht_rt5677_dailink[i].codecs->name == ctx->codec_name) { > > + cht_rt5677_dailink[i].codecs->name = RT5677_I2C_DEFAULT; > > + break; > > + } > > + } > > + > > + gpiod_put(ctx->gpio_hp_en); > > + gpiod_put(ctx->gpio_spk_en2); > > + gpiod_put(ctx->gpio_spk_en1); > > +} > > ... > > > diff --git a/sound/soc/intel/common/soc-acpi-intel-cht-match.c b/sound/soc/intel/common/soc-acpi-intel-cht-match.c > > index 5e8a1dc84ee1..c719c3ec8314 100644 > > --- a/sound/soc/intel/common/soc-acpi-intel-cht-match.c > > +++ b/sound/soc/intel/common/soc-acpi-intel-cht-match.c > > @@ -17,12 +17,11 @@ static struct snd_soc_acpi_mach cht_surface_mach = { > > .sof_tplg_filename = "sof-cht-rt5645.tplg", > > }; > > -static struct snd_soc_acpi_mach cht_yogabook_mach = { > > +static struct snd_soc_acpi_mach cht_rt5677_mach = { > > .id = "10EC5677", > > - .drv_name = "cht-yogabook", > > + .drv_name = "cht-rt5677", > > .fw_filename = "intel/fw_sst_22a8.bin", > > - .board = "cht-yogabook", > > - .sof_tplg_filename = "sof-cht-rt5677.tplg", > > + .board = "cht_rt5677", > > }; > > static struct snd_soc_acpi_mach cht_lenovo_yoga_tab3_x90_mach = { > > @@ -41,17 +40,9 @@ static const struct dmi_system_id cht_table[] = { > > DMI_MATCH(DMI_PRODUCT_NAME, "Surface 3"), > > }, > > }, > > - { > > - .ident = "Lenovo Yoga Book YB1-X91", > > - .driver_data = (void *)&cht_yogabook_mach, > > - /* YB1-X91L/F */ > > - .matches = { > > - DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X91"), > > - } > > - }, > > { > > .ident = "Lenovo Yoga Book YB1-X90", > > - .driver_data = (void *)&cht_yogabook_mach, > > + .driver_data = (void *)&cht_rt5677_mach, > > /* YB1-X90L/F, codec is not listed in DSDT */ > > .matches = { > > > > @@ -147,19 +138,11 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_cherrytrail_machines[] = { > > .board = "cht-bsw", > > .sof_tplg_filename = "sof-cht-rt5670.tplg", > > }, > > - /* > > - * The only known Cherry Trail device with RT5677 codec and 10EC677 > > - * DSTD entry is the Lenovo Yoga Book YB1-X91. It has a device-specific > > - * driver, so check DMI and use a machine quirk to override the default > > - * (non-existent) machine driver. > > - */ > > You are removing and editing (the below table) code you've just added with > 2/3. This looks very bad. Argh, it should have been integrated into the second patch in the series instead of this one... My bad, sorry. > > > { > > .id = "10EC5677", > > - .drv_name = "cht-bsw-rt5677", > > + .drv_name = "cht-rt5677", > > .fw_filename = "intel/fw_sst_22a8.bin", > > - .board = "cht-bsw", > > - .machine_quirk = cht_quirk, > > - .sof_tplg_filename = "sof-cht-rt5677.tplg", > > + .board = "cht_rt5677", > > }, > > { > > .comp_ids = &rt5645_comp_ids, > > > -- Yauhen Kharuzhy ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2026-06-11 21:53 UTC | newest] Thread overview: 11+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-06-10 23:51 [PATCH v3 0/3] Add ASoC machine driver for Cherryview tablets with RT5677 Yauhen Kharuzhy 2026-06-10 23:51 ` [PATCH v3 1/3] ASoC: Intel: soc-acpi-cht: Unify device quirks Yauhen Kharuzhy 2026-06-11 8:47 ` Cezary Rojewski 2026-06-11 14:10 ` Mark Brown 2026-06-11 18:05 ` Yauhen Kharuzhy 2026-06-11 18:12 ` Mark Brown 2026-06-10 23:51 ` [PATCH v3 2/3] ASoC: Intel: soc-acpi-cht: Add Lenovo Yoga Book entries Yauhen Kharuzhy 2026-06-11 8:50 ` Cezary Rojewski 2026-06-10 23:51 ` [PATCH v3 3/3] ASoC: Intel: Add cht_rt5677 driver Yauhen Kharuzhy 2026-06-11 9:19 ` Cezary Rojewski 2026-06-11 21:53 ` Yauhen Kharuzhy
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox