From nobody Fri Apr 3 04:58:20 2026 Received: from mail-ed1-f42.google.com (mail-ed1-f42.google.com [209.85.208.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8246121B191 for ; Sun, 1 Mar 2026 21:34:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.42 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772400847; cv=none; b=d3+Ag9RAvs4Pkgnog3II67ZAIgUp16pwTxkz1MS8zTWBPXQbnTyRZBZJMzaadcM6s8DSDsnYXS62MaqRyn2Dz/J7ABUUMKWI/9epYSYzxuMxC4KrN6RlTT2AEXc/BhkWcWZ/HAfRbTuwjAwmLXmWKwFETvW6mHjbZO8KBx3gkh8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772400847; c=relaxed/simple; bh=lM8CSz0ZAgw0noIwUoYPin1QYbAEN1swuFeYfH8WiOM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=PJ/3QCLmW4R3HFT66+nxjqe935QdG3lZ0lJQXCVlXDDhduKOMIYjnVQSg7uIFfwVjW0PkNqxC8qMSPGCh5YiqPP69jHLucyUVFXz2fMsA2B4129r1J4595UoAArGNr4FzHMBjcQO6WDnhekrX92GxXAzEx4wpOsw8P7kx+9ZtcE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=gSp3pcBr; arc=none smtp.client-ip=209.85.208.42 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="gSp3pcBr" Received: by mail-ed1-f42.google.com with SMTP id 4fb4d7f45d1cf-65f71ed7c6cso6560508a12.0 for ; Sun, 01 Mar 2026 13:34:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1772400844; x=1773005644; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=EsG6AI7p1nqWRSx0MJDSqDIjQsSAz68j9rdPzL7TnOQ=; b=gSp3pcBrTYthFKdr+28ysev2KbbT8wC/3BvwYOIKFUkvCqXcJzgEJ3EgaxXNNsGVUE WX71cZcwjSaUCUkj3xgJNsGX+1sZcBya3iT+fj8VKsv1J647DpcaD48ndIjf1Ou0KrQu DjcxhtAlTEhMENy+3/Feha++OgaGgBkr0XHi2fllklwmkO+Ld6vmvYuSeUsh7o61yhum 2XMmawFHV2VSM31pZIhVdceXzqj/F/z+rQHSfWYXEh9emS28P3x7ugXU7/2aFDShvlwP cIv+IJQCjSqFkSRhA56k9jCYStKxl7PqhPxSIYrMpuj0krD0l8WulyfwFOKEaCTHFm9s 3lWA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772400844; x=1773005644; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=EsG6AI7p1nqWRSx0MJDSqDIjQsSAz68j9rdPzL7TnOQ=; b=IzuvAogvMgFdXa9fJzhzH0hidyf/oI3f24cRA0aUJDJ0c/xGv4Pq9CusKaz3ryw+8o jnJXMHFZJXtuIAReJGznmhT1y2ktqOE4lOnH/dj+MgrcblnXJDp7zq7qbYKMkc7QjfND xLjNLvYdwPElGGsJTNrdNNStUzYSDIo2RTSnhx8HEnhE0N/onfFGKjF3RCfmVugd+4iS wC+e1PoOLeZYewIAt+Qxl422AoYMdv7Y0PngUByk8UsaHchX6ub1v0/iMqmFUex84ooS 8xLjaDmHXzoYLHHTEkIkP0fMtxOFxJTYZ7ynKjOTTmGcnefVYCenQmo7LQtiZuk0ZLL2 MGjw== X-Forwarded-Encrypted: i=1; AJvYcCVmiQonHmmuq+BGxQn8hu1clWfrQFqaYdUxn69/Z+AWojieFhyWweU478wEcnNcIQEJ0oZUj38Dc240fuY=@vger.kernel.org X-Gm-Message-State: AOJu0YxGzyn/fvvwghuAvsF/ezVmW4KzH8CC4Epc7Q0u8CFT47q1YCKQ ui7toH349QqUgNYhv6Olm+TeWaQRoAkf9N2NV2jEHuL6ZTMMhPfQzJdJcj85pd7T X-Gm-Gg: ATEYQzzEX6GQShlrbXTwjdaMGb7kNd49CbZpRMou89Jk1Smza+Tus91PvdEccUfj587 Eh3GSz0876swG11j3+XFjksC+aek00HigqZvmxnlY7RoHeLZ9RyeauKhntbVKRi5630FPhgfHpI TxubHw0YdUqCsjWrl0tgRAe1XdqtYrMgfTA4hLdg/8/AfooJYyHNV3v+lt+6BZjbyFPqxA0szTP TtfaAKJsuGQuIaGug59itEkxnhWk1EME7WO4QJSiYGfkb3DdvOKKMmNUs9AwPTa0Q6wGIPYwiVO 85tfjIzP3+Xun8sIKbiHjEIzr4O4LWUNqSrLkWFD33muphkn7tHu91WBQ41afPIBkYolngVVcNN JGEdPXGxM6w3zi1SNDNbq4Qyzaw1yWV/Z38CAz/SwrZ3/k4fwMnqZ1v4ggbDzaGfSFVAXEP6esU f9chO1+I1PAqaLdsoizA== X-Received: by 2002:a05:6402:2755:b0:65f:830b:1034 with SMTP id 4fb4d7f45d1cf-65fdd6bd91bmr6814260a12.6.1772400843423; Sun, 01 Mar 2026 13:34:03 -0800 (PST) Received: from [127.0.1.1] ([46.251.53.180]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-65fabf6cfd9sm2934793a12.22.2026.03.01.13.34.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 01 Mar 2026 13:34:02 -0800 (PST) From: Yauhen Kharuzhy Date: Sun, 01 Mar 2026 23:33:44 +0200 Subject: [PATCH v2 1/3] ASoC: Intel: soc-acpi-cht: Unify device quirks Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260301-asoc-yogabook-v2-v2-1-adcc7ed40985@gmail.com> References: <20260301-asoc-yogabook-v2-v2-0-adcc7ed40985@gmail.com> In-Reply-To: <20260301-asoc-yogabook-v2-v2-0-adcc7ed40985@gmail.com> To: Cezary Rojewski , Liam Girdwood , Peter Ujfalusi , Bard Liao , Ranjani Sridharan , Kai Vehmanen , Pierre-Louis Bossart , Mark Brown Cc: linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org, Hans de Goede , Yauhen Kharuzhy X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1772400841; l=5864; i=jekhor@gmail.com; s=20260301; h=from:subject:message-id; bh=lM8CSz0ZAgw0noIwUoYPin1QYbAEN1swuFeYfH8WiOM=; b=JbfeDRs0yg23M6QPpyUd9mijcWCGHTNQAind0YtJfZwW2pOefIal+eeifYIbbPxb0yp4Siij/ XHH9bCRvrSsAYfvUV4+Z9vUdy+tEYyk/r4pZsPmiR3WFeNc7RWGTenm X-Developer-Key: i=jekhor@gmail.com; a=ed25519; pk=C/csaZJs7UBNDgeJcUAmPu4ntqNeaZ3BKfBQiH8tuGc= 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 --- 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..57097c1d011e 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 #include =20 -static unsigned long cht_machine_id; - -#define CHT_SURFACE_MACH 1 +static struct snd_soc_acpi_mach cht_surface_mach =3D { + .id =3D "10EC5640", + .drv_name =3D "cht-bsw-rt5645", + .fw_filename =3D "intel/fw_sst_22a8.bin", + .board =3D "cht-bsw", + .sof_tplg_filename =3D "sof-cht-rt5645.tplg", +}; =20 -static int cht_surface_quirk_cb(const struct dmi_system_id *id) -{ - cht_machine_id =3D CHT_SURFACE_MACH; - return 1; -} +static struct snd_soc_acpi_mach cht_lenovo_yoga_tab3_x90_mach =3D { + .id =3D "10WM5102", + .drv_name =3D "bytcr_wm5102", + .fw_filename =3D "intel/fw_sst_22a8.bin", + .board =3D "bytcr_wm5102", + .sof_tplg_filename =3D "sof-cht-wm5102.tplg", +}; =20 static const struct dmi_system_id cht_table[] =3D { { - .callback =3D cht_surface_quirk_cb, + .driver_data =3D (void *)&cht_surface_mach, .matches =3D { 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 =3D (void *)&cht_lenovo_yoga_tab3_x90_mach, + .matches =3D { + DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), + DMI_MATCH(DMI_PRODUCT_VERSION, "Blade3-10A-001"), + }, + }, { } }; =20 -static struct snd_soc_acpi_mach cht_surface_mach =3D { - .id =3D "10EC5640", - .drv_name =3D "cht-bsw-rt5645", - .fw_filename =3D "intel/fw_sst_22a8.bin", - .board =3D "cht-bsw", - .sof_tplg_filename =3D "sof-cht-rt5645.tplg", -}; - static struct snd_soc_acpi_mach *cht_quirk(void *arg) { struct snd_soc_acpi_mach *mach =3D arg; + const struct dmi_system_id *match; =20 - dmi_check_system(cht_table); - - if (cht_machine_id =3D=3D CHT_SURFACE_MACH) - return &cht_surface_mach; + match =3D dmi_first_match(cht_table); + if (match) + return (struct snd_soc_acpi_mach *)match->driver_data; else return mach; } =20 +static struct snd_soc_acpi_mach *cht_quirk_nocodec(void *arg) +{ + struct snd_soc_acpi_mach *mach =3D cht_quirk(arg); + + return mach =3D=3D 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 DS= DTs @@ -75,38 +91,6 @@ static struct snd_soc_acpi_mach *cht_ess8316_quirk(void = *arg) return arg; } =20 -/* - * 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[] =3D { - { - /* Lenovo Yoga Tab 3 Pro YT3-X90, codec missing from DSDT */ - .matches =3D { - 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 =3D { - .id =3D "10WM5102", - .drv_name =3D "bytcr_wm5102", - .fw_filename =3D "intel/fw_sst_22a8.bin", - .board =3D "bytcr_wm5102", - .sof_tplg_filename =3D "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 =3D { .num_codecs =3D 2, .codecs =3D { "10EC5640", "10EC3276" }, @@ -208,14 +192,14 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_cherrytr= ail_machines[] =3D { .sof_tplg_filename =3D "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 =3D "808622A8", - .machine_quirk =3D lenovo_yt3_x90_quirk, + .machine_quirk =3D cht_quirk_nocodec, }, =20 #if IS_ENABLED(CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH) --=20 2.51.0 From nobody Fri Apr 3 04:58:20 2026 Received: from mail-ed1-f46.google.com (mail-ed1-f46.google.com [209.85.208.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 64D9C21E098 for ; Sun, 1 Mar 2026 21:34:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772400847; cv=none; b=hpho6/Tamn2MIF5vqjRBXxAx8suIUzKhqVmqga+YywYtWWkydg3YZwl1RC2xnGOgc/sDKkKWc8QCSzN1mOl7ES9xH6NEoOX8huo0GX+MlZg5WrjFoDl/q2IbyQHRIN+p8Sg//P5RxWFpBUmujMhCuRm2jrGSbNAi3/vdvvOncpQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772400847; c=relaxed/simple; bh=B8FnKyLJmR2ho+Z9gxg55SrZBzenyK2GQpiJ5FVZin4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=U8Fsxhg0FmX+bprEs5E7KR7ScL2SPCQDvHCJhaXNuoWXszP88UZhBvZxGKxLPikVp9Mz+b6KEQv7SVEE3WacH3AV6ZE4vUe9YHG+ZFFpBkA35uCqTKfuUPDk6MwzZmuoJhUelGheRUGO8b+ZEEq4LDJvHlrHt1xfYils1kPEACw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=YfzljBbn; arc=none smtp.client-ip=209.85.208.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="YfzljBbn" Received: by mail-ed1-f46.google.com with SMTP id 4fb4d7f45d1cf-65fa79f5c98so6365293a12.1 for ; Sun, 01 Mar 2026 13:34:06 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1772400845; x=1773005645; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=mEUARIzmZmUzYn3fC8mAujTGgUYKtVNaTf4bY9B92SY=; b=YfzljBbnl2N3PO4Sa9qwnQh2j+kz1iaSg1kZkqsQjkluXvjKJenzyGYOfI5TFqXdvH egM8d5F45ShNZMOReY37LmpZOkF6r3yNxd31aMg238lZG/NhXRCHZAolqBk8LbCexrFE 1aTcDlJL1EiuNdEEtRHAuhVlbf+rkAI7K/dMYqDztdfolmcXI2LeNq7h6vNYyp0OlOGi s6fumKdDAsWxlkH3tVMD7gHBTyX+QYUQBkUs2Fy6O3zdnhlp42EqpXkm7NrVsSdn/7Cf E3lT9WB1pNZn6bdszclbOBO1rO3QTdmjpy7nYg9xlJj8Doy7MijOmkrlhHJ3tCHaJeld GS+Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772400845; x=1773005645; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=mEUARIzmZmUzYn3fC8mAujTGgUYKtVNaTf4bY9B92SY=; b=tH7a0LgHakghCTavlL0pyAfFnDHafNbN/79cJ2YgO62nkzUbjfRZs41k4kLTD7kqXD s4dLSAU3yXyicxSmq+rDdTmpx34g/+r/2ntSPNiIvLAG64D2moPBgvZWGPj9uzSA/Cue GMKTuD1khM0p0z2tSuExtAg2v87WkI5WfvL4oiQj/BACavp030ztS+gbniI4b9Kq013L 0HyQYauWB28r8EmsRD1SPKsVoX3XdfnICVgmT483gT5Ho/hQc+2E3aQdm9jjLhb1HfZF Bjg/fnAEAPkC+dFER58MOq0RJ3TrR05kACiQ+CQkBFhD9UvdhRaQKhUs5ebfmzw6GbI6 adOw== X-Forwarded-Encrypted: i=1; AJvYcCUOXN60ZmCq9W7TIiO4ci1nZVPdyqrlrinJoDk5O9KICKyga+qM2JYUu1wgOgPOM5/3LRIzUeej7m8zE7k=@vger.kernel.org X-Gm-Message-State: AOJu0YxtoYdu8GchFSBeqxXaLoiLaxc3cSHDCVdiSAauqRXFTOpz4nJc 9JiWWUBpDL/ujWcbBLji07ivGgstD0wvS0Rw23MZkZkQlX4kLpyJvJ+t X-Gm-Gg: ATEYQzzIDxoUAcOCh7s6Cc4/fwg/5iLN7PI5h30Q28oQMaIJDM1OL5JBOBdTbgJxHX3 NOlcyWUZ6EKaIcDZXGo0rJyFp5wEs1CIbEIQy79CuvM7EOWYgK4Xa6o/nxtfLZ4+s6RC30+/5Ik vZbFIVODn39aLBdIHFqg17+320RNfnEkCD1z5YMlJV/0d6VaZUCyQ5Ls4LpT8cIEeJvuC/nEnt7 JhtwhjAXBDZX732vqaFBP+v2Soafh66G7YZzEBQZ+I2XQyELb/19UsLibCDBliXszTRfJtmGN3x TLf5JcwWFP0z2vVcNpL/VA36KCsh5QOHYC3XM6WceUnU8Bz2bNW1sz+qMTA7opwI5amKy1lTXp6 rd/5xOoMwamTLMlQKMoJLHqZEFDwWwFLzNj7b0OJ8xZxt6abXQrFstF3PycUWY8yx4mRszyCQQX pkCeAZb5lI6sp3sB5NeQ== X-Received: by 2002:a05:6402:d0e:b0:65c:76a6:4bdc with SMTP id 4fb4d7f45d1cf-65fe2d48286mr5371232a12.9.1772400844623; Sun, 01 Mar 2026 13:34:04 -0800 (PST) Received: from [127.0.1.1] ([46.251.53.180]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-65fabf6cfd9sm2934793a12.22.2026.03.01.13.34.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 01 Mar 2026 13:34:04 -0800 (PST) From: Yauhen Kharuzhy Date: Sun, 01 Mar 2026 23:33:45 +0200 Subject: [PATCH v2 2/3] ASoC: Intel: soc-acpi-cht: Add Lenovo Yoga Book entries Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260301-asoc-yogabook-v2-v2-2-adcc7ed40985@gmail.com> References: <20260301-asoc-yogabook-v2-v2-0-adcc7ed40985@gmail.com> In-Reply-To: <20260301-asoc-yogabook-v2-v2-0-adcc7ed40985@gmail.com> To: Cezary Rojewski , Liam Girdwood , Peter Ujfalusi , Bard Liao , Ranjani Sridharan , Kai Vehmanen , Pierre-Louis Bossart , Mark Brown Cc: linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org, Hans de Goede , Yauhen Kharuzhy X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1772400841; l=3008; i=jekhor@gmail.com; s=20260301; h=from:subject:message-id; bh=B8FnKyLJmR2ho+Z9gxg55SrZBzenyK2GQpiJ5FVZin4=; b=LsCIpY6MH6aZ+5U3s7JgLAGUxGBxgC3acKtnHrnItgo6aWnTF1CTkNSqfXk4sZPYsecjAUuE6 4aj3WPCWzLKDT5CgTbo2t6NcHMRBS19RZAB5680LxGK3SkRKT7ldkic X-Developer-Key: i=jekhor@gmail.com; a=ed25519; pk=C/csaZJs7UBNDgeJcUAmPu4ntqNeaZ3BKfBQiH8tuGc= 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 --- 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 57097c1d011e..8673ade66e9d 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 =3D { .sof_tplg_filename =3D "sof-cht-rt5645.tplg", }; =20 +static struct snd_soc_acpi_mach cht_yogabook_mach =3D { + .id =3D "10EC5677", + .drv_name =3D "cht-yogabook", + .fw_filename =3D "intel/fw_sst_22a8.bin", + .board =3D "cht-yogabook", + .sof_tplg_filename =3D "sof-cht-rt5677.tplg", +}; + static struct snd_soc_acpi_mach cht_lenovo_yoga_tab3_x90_mach =3D { .id =3D "10WM5102", .drv_name =3D "bytcr_wm5102", @@ -33,6 +41,24 @@ static const struct dmi_system_id cht_table[] =3D { DMI_MATCH(DMI_PRODUCT_NAME, "Surface 3"), }, }, + { + .ident =3D "Lenovo Yoga Book YB1-X91", + .driver_data =3D (void *)&cht_yogabook_mach, + /* YB1-X91L/F */ + .matches =3D { + DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X91"), + } + }, + { + .ident =3D "Lenovo Yoga Book YB1-X90", + .driver_data =3D (void *)&cht_yogabook_mach, + /* YB1-X90L/F, codec is not listed in DSDT */ + .matches =3D { + 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_cherrytra= il_machines[] =3D { .board =3D "cht-bsw", .sof_tplg_filename =3D "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 =3D "10EC5677", + .drv_name =3D "cht-bsw-rt5677", + .fw_filename =3D "intel/fw_sst_22a8.bin", + .board =3D "cht-bsw", + .machine_quirk =3D cht_quirk, + .sof_tplg_filename =3D "sof-cht-rt5677.tplg", + }, { .comp_ids =3D &rt5645_comp_ids, .drv_name =3D "cht-bsw-rt5645", --=20 2.51.0 From nobody Fri Apr 3 04:58:20 2026 Received: from mail-ej1-f43.google.com (mail-ej1-f43.google.com [209.85.218.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CD3B42F5A06 for ; Sun, 1 Mar 2026 21:34:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772400850; cv=none; b=N3IUQjJgd5UUSQCILtUa4lMglQ2UOtRUUNvCyzD1gmQHDhSsgyN4FjsqbH5yjPyY6JzW0ky7v2KCjMTA65HqWJGbzB/vZ7kecbqrFdOvONa3MRRBGvn22M6gaE+rzCh1z6rxe4OSNhtX5ZXTDJ17U43vVG4D8tTwP01odiVkIns= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772400850; c=relaxed/simple; bh=qVAI0cy4vwnSShSUyt2bELrLj2tIIw5QyEWW7tT4m24=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=qwDdlnKJm1Urs7ZeC1Ndj1KWvssgC+x0q0dp7jourBpViCK79V8swb01iv8U1s6AVe3UP5vndf5iG6UfQAGYdH28Vfl3i31Fk/hscG6WvLmDc3GJCHBy2lG+UGZtgtFKRS5iTJODiTeT7/I3cnfARcoPEwSkK/moK0cyjLpNk0w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=b1rYfVgq; arc=none smtp.client-ip=209.85.218.43 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="b1rYfVgq" Received: by mail-ej1-f43.google.com with SMTP id a640c23a62f3a-b8fb6ad3243so566873466b.1 for ; Sun, 01 Mar 2026 13:34:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1772400846; x=1773005646; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=eua0+RXtpU2H7UelcO0dLJIQrVhWLZK4LeM9+ZoYzZY=; b=b1rYfVgqEuA+ais2EsQYmRMFYPRUq0Ko/u9apTvB1jcbxu5r2COtzv1e2SezLh+Mlt WSpJdE8Qnf2ct+Oloz/tTLpCuMrxPxWBA0+s+XUF0euLLSf/SaPR7qClV1X5/PewY0yH xk0vrpuyGxEB3HLrO/MZX5mlRcc4vJMKWFRYTognpwy1qY119gUTeUQyxzyqU3kvFYF8 n6IBpNi8nww/4TqVSCo1Us8RbkUibxtXYMLMRZo6nm6Unn6340KpuocvoDXrbSS1aPfw y4f69sjQsPAbkNqTsZrnhSOoe/UvU9O/dzvB67ahb4JbNaMcrv6Sb/bTK5tsVH2ZwHF8 9P5w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772400846; x=1773005646; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=eua0+RXtpU2H7UelcO0dLJIQrVhWLZK4LeM9+ZoYzZY=; b=BGEi4yTNE3B6/idg1fE7PidyFGEI6nansRK9QNSUPECv73fa2igQo6na5HEzcianFD a5sCbEjUo9H7AGciJZRQCgirN7K9KLn8h6dWt/Zdsuqg2xVmohHY0N17obXjWG5x4ZiE LAYgvR6tDfiHkIn6T1TIE65LqNnLdHVcQCZoGsiA5iXoljJQT8jpKpKgUrG2Oq3zkgj2 uwiMOugeYQyybppcPwMw8b/t/RaEFxUGdGKgTVQGnPs77F9Uc7yS+THLNqqd1X3hwFau 2IEgo57O6QrijYw79CXtLd9M6+GvMZF7yG49Zny7PtE3iK69JLAA+EM5UdpaaJLdaSdH lvFw== X-Forwarded-Encrypted: i=1; AJvYcCV4sPrQEs23i/AEN0ET/7wNvy5IHI+A+FqL0ES8/ixASEB9Y5s0WtjAWti8/1qz8wL+rrolhG+hn0eow9Q=@vger.kernel.org X-Gm-Message-State: AOJu0YxmWWnLHstYJfV6XnogiZBx/Z8DwaNMZC7SkPYVpuXQWQqF5ldk JERLvAqFuEHuZreQcAPxPi446qw+iBCR25dRbemT1CoZgUxHxXvg9O+B X-Gm-Gg: ATEYQzyloXn92uFq1OffOT416ikf3A+/+g6s0s21N4f7h06IlZp1XcjNfhB+9ovp/29 Pd9hySxLBkcQ/QknWUYtYtkOyXa95vAGBvhvtATC1F/khGIocfqDEZ/hdkFzRTJ8B4fBzVeyn5a PYyUz3UaC7O4i2ayj0cnZjnNv9hvxQlJdy3zet73NELAgzTHnjTxw6etPaPKVJ7j6bWKk7A6KG6 sg+pimDEq1JxaRqvzi9zpXPFecnJj7Sbvg6ptnsJJG+9YXmE4VOh3vwWvNyKyBqsL5sCLnsEneg oEl8D9yb3z4ooU6voKS6DEdDs7rI4cRzrrdacUI10TcaswnCOAdmwx0gQjI6k1PGIdjv6UqwNmJ TWe2Duzi6VnLvmmH4HYYcX5tzrQFV4Ci94jTPYJyJqJJZRJGkAUOMJ/iSzN+YvwvfxaODQlLWJo fQdzW1nzs6YWBpg6U3wA== X-Received: by 2002:a17:907:7f8a:b0:b8e:9d66:f5fb with SMTP id a640c23a62f3a-b937616f277mr568593766b.0.1772400845618; Sun, 01 Mar 2026 13:34:05 -0800 (PST) Received: from [127.0.1.1] ([46.251.53.180]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-65fabf6cfd9sm2934793a12.22.2026.03.01.13.34.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 01 Mar 2026 13:34:05 -0800 (PST) From: Yauhen Kharuzhy Date: Sun, 01 Mar 2026 23:33:46 +0200 Subject: [PATCH v2 3/3] ASoC: Intel: cht_yogabook: Add driver for Lenovo Yoga Book tablets Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260301-asoc-yogabook-v2-v2-3-adcc7ed40985@gmail.com> References: <20260301-asoc-yogabook-v2-v2-0-adcc7ed40985@gmail.com> In-Reply-To: <20260301-asoc-yogabook-v2-v2-0-adcc7ed40985@gmail.com> To: Cezary Rojewski , Liam Girdwood , Peter Ujfalusi , Bard Liao , Ranjani Sridharan , Kai Vehmanen , Pierre-Louis Bossart , Mark Brown Cc: linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org, Hans de Goede , Yauhen Kharuzhy X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1772400841; l=20169; i=jekhor@gmail.com; s=20260301; h=from:subject:message-id; bh=qVAI0cy4vwnSShSUyt2bELrLj2tIIw5QyEWW7tT4m24=; b=C3Iz4CjDYN261gkNVkvpp8cePFfSZpO/YJJRvyO70C/IukZ2nedHVdYodEDJ/1JbyjgBBdJpF zUjRlZdPOqFA5wqA+naVVWZOljkmD2vpsiv5AeQw9NGTKeR04Am15vW X-Developer-Key: i=jekhor@gmail.com; a=ed25519; pk=C/csaZJs7UBNDgeJcUAmPu4ntqNeaZ3BKfBQiH8tuGc= Add a new ASoC machine driver for Lenovo Yoga Book Intel Cherry Trail-based tablets (YB1-X90F/L, YB1-X91F/L models). 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 the driver is named 'cht_yogabook', and 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 --- sound/soc/intel/boards/Kconfig | 15 + sound/soc/intel/boards/Makefile | 2 + sound/soc/intel/boards/cht_yogabook.c | 551 ++++++++++++++++++++++++++++++= ++++ 3 files changed, 568 insertions(+) diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig index c5942b5655d3..f7346ee085e7 100644 --- a/sound/soc/intel/boards/Kconfig +++ b/sound/soc/intel/boards/Kconfig @@ -237,6 +237,21 @@ config SND_SOC_INTEL_BYT_CHT_ES8316_MACH Say Y or m if you have such a device. This is a recommended option. If unsure select "N". =20 +config SND_SOC_INTEL_CHT_YOGABOOK_MACH + tristate "Cherrytrail-based Lenovo Yoga Book tablet" + 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 the Lenovo Yoga Book + tablets based on CherryTrail platform with RT5677 audio codec, models + YB1-X90F, YB1-X90L, YB1-X91F, YB1-X91L. + Say Y or m if you have such a device. This is a recommended opti= on. + If unsure select "N". + endif ## SND_SST_ATOM_HIFI2_PLATFORM || SND_SOC_SOF_BAYTRAIL =20 if SND_SST_ATOM_HIFI2_PLATFORM diff --git a/sound/soc/intel/boards/Makefile b/sound/soc/intel/boards/Makef= ile index 25a1a9066cbf..58bd6029545b 100644 --- a/sound/soc/intel/boards/Makefile +++ b/sound/soc/intel/boards/Makefile @@ -15,6 +15,7 @@ snd-soc-sst-cht-bsw-nau8824-y :=3D cht_bsw_nau8824.o snd-soc-sst-byt-cht-cx2072x-y :=3D bytcht_cx2072x.o snd-soc-sst-byt-cht-da7213-y :=3D bytcht_da7213.o snd-soc-sst-byt-cht-es8316-y :=3D bytcht_es8316.o +snd-soc-sst-cht-yogabook-objs :=3D cht_yogabook.o snd-soc-sst-byt-cht-nocodec-y :=3D bytcht_nocodec.o snd-soc-sof_rt5682-y :=3D sof_rt5682.o snd-soc-sof_cs42l42-y :=3D sof_cs42l42.o @@ -47,6 +48,7 @@ obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_NAU8824_MACH) +=3D snd= -soc-sst-cht-bsw-nau8824. obj-$(CONFIG_SND_SOC_INTEL_BYT_CHT_CX2072X_MACH) +=3D snd-soc-sst-byt-cht-= cx2072x.o obj-$(CONFIG_SND_SOC_INTEL_BYT_CHT_DA7213_MACH) +=3D snd-soc-sst-byt-cht-d= a7213.o obj-$(CONFIG_SND_SOC_INTEL_BYT_CHT_ES8316_MACH) +=3D snd-soc-sst-byt-cht-e= s8316.o +obj-$(CONFIG_SND_SOC_INTEL_CHT_YOGABOOK_MACH) +=3D snd-soc-sst-cht-yogaboo= k.o obj-$(CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH) +=3D snd-soc-sst-byt-cht-= nocodec.o obj-$(CONFIG_SND_SOC_INTEL_SKL_HDA_DSP_GENERIC_MACH) +=3D snd-soc-skl_hda_= dsp.o obj-$(CONFIG_SND_SOC_INTEL_EHL_RT5660_MACH) +=3D snd-soc-ehl-rt5660.o diff --git a/sound/soc/intel/boards/cht_yogabook.c b/sound/soc/intel/boards= /cht_yogabook.c new file mode 100644 index 000000000000..9d945cad5660 --- /dev/null +++ b/sound/soc/intel/boards/cht_yogabook.c @@ -0,0 +1,551 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * cht_yogabook.c - ASoc Machine driver for Lenovo Yoga Book YB1-X90/X91 + * tablets, based on Intel Cherrytrail platform with RT5677 codec. + * + * Copyright (C) 2026 Yauhen Kharuzhy + * + * Based on cht_bsw_rt5672.c: + * Copyright (C) 2014 Intel Corp + * Author: Subhransu S. Prusty + * Mengdong Lin + * + * And based on the cht_bl_dpcm_rt5677.c from the Lenovo's Android kernel: + * Copyright (C) 2014 Intel Corp + * Author: Mythri P K + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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_yb_private { + 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_yb_platform_clock_control(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) +{ + struct snd_soc_card *card =3D snd_soc_dapm_to_card(w->dapm); + struct snd_soc_dai *codec_dai; + struct cht_yb_private *ctx =3D snd_soc_card_get_drvdata(card); + int ret; + + codec_dai =3D 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)) { + if (ctx->mclk) { + ret =3D clk_prepare_enable(ctx->mclk); + if (ret < 0) { + dev_err(card->dev, + "could not configure MCLK state"); + return ret; + } + } + + /* set codec PLL source to the 19.2MHz platform clock (MCLK) */ + ret =3D 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 =3D 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; + } + } else { + /* 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); + + if (ctx->mclk) + clk_disable_unprepare(ctx->mclk); + } + return 0; +} + +static int cht_yb_hp_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) +{ + struct snd_soc_card *card =3D snd_soc_dapm_to_card(w->dapm); + struct cht_yb_private *ctx =3D snd_soc_card_get_drvdata(card); + + dev_dbg(card->dev, "HP event: %s\n", + SND_SOC_DAPM_EVENT_ON(event) ? "ON" : "OFF"); + + gpiod_set_value_cansleep(ctx->gpio_hp_en, SND_SOC_DAPM_EVENT_ON(event)); + + return 0; +} + +static int cht_yb_spk_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) +{ + struct snd_soc_card *card =3D snd_soc_dapm_to_card(w->dapm); + struct cht_yb_private *ctx =3D snd_soc_card_get_drvdata(card); + + dev_dbg(card->dev, "SPK event: %s\n", + SND_SOC_DAPM_EVENT_ON(event) ? "ON" : "OFF"); + + 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_yb_dapm_widgets[] =3D { + SND_SOC_DAPM_HP("Headphone", cht_yb_hp_event), + SND_SOC_DAPM_MIC("Headset Mic", NULL), + SND_SOC_DAPM_MIC("Int Mic", NULL), + SND_SOC_DAPM_SPK("Speaker", cht_yb_spk_event), + SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, + cht_yb_platform_clock_control, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), +}; + +static const struct snd_soc_dapm_route cht_yb_audio_map[] =3D { + {"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_mc_controls[] =3D { + 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_yb_aif1_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd =3D substream->private_data; + struct snd_soc_dai *codec_dai =3D snd_soc_rtd_to_codec(rtd, 0); + int ret; + + /* set codec PLL source to the 19.2MHz platform clock (MCLK) */ + ret =3D 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 =3D 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 =3D 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 =3D 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_yb_codec_init(struct snd_soc_pcm_runtime *runtime) +{ + int ret =3D 0; + struct snd_soc_dai *codec_dai =3D snd_soc_rtd_to_codec(runtime, 0); + struct snd_soc_component *component =3D codec_dai->component; + struct cht_yb_private *ctx =3D snd_soc_card_get_drvdata(runtime->card); + + /* 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); + + ctx->gpio_spk_en1 =3D devm_gpiod_get(component->dev, "speaker-enable", + GPIOD_OUT_LOW); + if (IS_ERR(ctx->gpio_spk_en1)) { + dev_err(component->dev, "Can't find speaker enable GPIO\n"); + return PTR_ERR(ctx->gpio_spk_en1); + } + + ctx->gpio_spk_en2 =3D devm_gpiod_get(component->dev, "speaker-enable2", + GPIOD_OUT_LOW); + if (IS_ERR(ctx->gpio_spk_en2)) { + dev_err(component->dev, "Can't find speaker enable 2 GPIO\n"); + return PTR_ERR(ctx->gpio_spk_en2); + } + + ctx->gpio_hp_en =3D devm_gpiod_get(component->dev, "headphone-enable", + GPIOD_OUT_LOW); + if (IS_ERR(ctx->gpio_hp_en)) { + dev_err(component->dev, "Can't find headphone enable GPIO\n"); + return PTR_ERR(ctx->gpio_hp_en); + } + + if (ctx->mclk) { + /* + * 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 =3D clk_prepare_enable(ctx->mclk); + if (!ret) + clk_disable_unprepare(ctx->mclk); + + ret =3D 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_yb_codec_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_interval *rate =3D hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels =3D hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + + /* The DSP will convert the FE rate to 48k, stereo, 24bits */ + rate->min =3D rate->max =3D 48000; + channels->min =3D channels->max =3D 2; + + /* set SSP2 to 24-bit */ + params_set_format(params, SNDRV_PCM_FORMAT_S24_LE); + + return 0; +} + +static struct snd_soc_jack_pin cht_yb_jack_pins[] =3D { + { + .pin =3D "Headphone", + .mask =3D SND_JACK_HEADPHONE, + }, + { + .pin =3D "Headset Mic", + .mask =3D SND_JACK_MICROPHONE, + }, +}; + +static int cht_yb_headset_init(struct snd_soc_component *component) +{ + struct snd_soc_card *card =3D component->card; + struct cht_yb_private *ctx =3D snd_soc_card_get_drvdata(card); + struct snd_soc_jack *jack =3D &ctx->jack; + int jack_type; + int ret; + + /* + * TS3A227E supports 4 butons headset detection + * KEY_MEDIA + * KEY_VOICECOMMAND + * KEY_VOLUMEUP + * KEY_VOLUMEDOWN + */ + jack_type =3D SND_JACK_HEADPHONE | SND_JACK_MICROPHONE | + SND_JACK_BTN_0 | SND_JACK_BTN_1 | + SND_JACK_BTN_2 | SND_JACK_BTN_3; + + ret =3D snd_soc_card_jack_new_pins(card, "Headset Jack", + jack_type, jack, + cht_yb_jack_pins, + ARRAY_SIZE(cht_yb_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_yb_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_yb_aif1_ops =3D { + .startup =3D cht_yb_aif1_startup, +}; + +static const struct snd_soc_ops cht_yb_be_ssp2_ops =3D { + .hw_params =3D cht_yb_aif1_hw_params, +}; + +static struct snd_soc_aux_dev cht_yb_headset_dev =3D { + .dlc =3D COMP_AUX("i2c-ts3a227e"), + .init =3D cht_yb_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_yb_dailink[] =3D { + /* Front End DAI links */ + [MERR_DPCM_AUDIO] =3D { + .name =3D "Audio Port", + .stream_name =3D "Audio", + .nonatomic =3D true, + .dynamic =3D 1, + .ops =3D &cht_yb_aif1_ops, + SND_SOC_DAILINK_REG(media, dummy, platform), + }, + [MERR_DPCM_DEEP_BUFFER] =3D { + .name =3D "Deep-Buffer Audio Port", + .stream_name =3D "Deep-Buffer Audio", + .nonatomic =3D true, + .dynamic =3D 1, + .playback_only =3D 1, + .ops =3D &cht_yb_aif1_ops, + SND_SOC_DAILINK_REG(deepbuffer, dummy, platform), + }, + + /* Back End DAI links */ + { + /* SSP2 - Codec */ + .name =3D "SSP2-Codec", + .id =3D 0, + .no_pcm =3D 1, + .nonatomic =3D true, + .init =3D cht_yb_codec_init, + .be_hw_params_fixup =3D cht_yb_codec_fixup, + .ops =3D &cht_yb_be_ssp2_ops, + SND_SOC_DAILINK_REG(ssp2_port, ssp2_codec, platform), + }, +}; + +/* SoC card */ +static struct snd_soc_card snd_soc_card_cht_yb =3D { + .owner =3D THIS_MODULE, + .dai_link =3D cht_yb_dailink, + .num_links =3D ARRAY_SIZE(cht_yb_dailink), + .aux_dev =3D &cht_yb_headset_dev, + .num_aux_devs =3D 1, + .dapm_widgets =3D cht_yb_dapm_widgets, + .num_dapm_widgets =3D ARRAY_SIZE(cht_yb_dapm_widgets), + .dapm_routes =3D cht_yb_audio_map, + .num_dapm_routes =3D ARRAY_SIZE(cht_yb_audio_map), + .controls =3D cht_mc_controls, + .num_controls =3D ARRAY_SIZE(cht_mc_controls), +}; + +static const struct acpi_gpio_params speaker_enable_gpio =3D { 2, 0, false= }; +static const struct acpi_gpio_mapping cht_yb_gpios[] =3D { + { "speaker-enable-gpios", &speaker_enable_gpio, 1 }, + { NULL } +}; + +#define SOF_CARD_NAME "cht yogabook" +#define SOF_DRIVER_NAME "SOF" + +#define CARD_NAME "cht-yogabook" +#define DRIVER_NAME NULL + +static int snd_cht_yb_mc_probe(struct platform_device *pdev) +{ + int ret_val =3D 0; + struct cht_yb_private *drv; + struct snd_soc_acpi_mach *mach =3D pdev->dev.platform_data; + const char *platform_name; + struct acpi_device *adev; + struct device *codec_dev; + bool sof_parent; + int i; + + drv =3D devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL); + if (!drv) + return -ENOMEM; + + strscpy(drv->codec_name, RT5677_I2C_DEFAULT); + + /* fixup codec name based on HID if ACPI node is present */ + adev =3D acpi_dev_get_first_match_dev(mach->id, NULL, -1); + if (adev) { + snprintf(drv->codec_name, sizeof(drv->codec_name), + "i2c-%s", acpi_dev_name(adev)); + dev_info(&pdev->dev, "real codec name: %s\n", drv->codec_name); + + put_device(&adev->dev); + for (i =3D 0; i < ARRAY_SIZE(cht_yb_dailink); i++) { + if (cht_yb_dailink[i].codecs->name && + !strcmp(cht_yb_dailink[i].codecs->name, + RT5677_I2C_DEFAULT)) { + cht_yb_dailink[i].codecs->name =3D drv->codec_name; + break; + } + } + } + + codec_dev =3D bus_find_device_by_name(&i2c_bus_type, NULL, + drv->codec_name); + if (!codec_dev) + return -EPROBE_DEFER; + + if (adev) { + ret_val =3D devm_acpi_dev_add_driver_gpios(codec_dev, + cht_yb_gpios); + if (ret_val) + dev_warn(&pdev->dev, + "Unable to add GPIO mapping table: %d\n", + ret_val); + } + + /* override platform name, if required */ + snd_soc_card_cht_yb.dev =3D &pdev->dev; + platform_name =3D mach->mach_params.platform; + + ret_val =3D snd_soc_fixup_dai_links_platform_name(&snd_soc_card_cht_yb, + platform_name); + if (ret_val) { + dev_err(&pdev->dev, + "snd_soc_fixup_dai_links_platform_name failed: %d\n", + ret_val); + return ret_val; + } + + drv->mclk =3D devm_clk_get(&pdev->dev, "pmc_plt_clk_3"); + if (IS_ERR(drv->mclk)) { + dev_err(&pdev->dev, + "Failed to get MCLK from pmc_plt_clk_3: %ld\n", + PTR_ERR(drv->mclk)); + return PTR_ERR(drv->mclk); + } + snd_soc_card_set_drvdata(&snd_soc_card_cht_yb, drv); + + sof_parent =3D snd_soc_acpi_sof_parent(&pdev->dev); + + /* set the card and driver name */ + if (sof_parent) { + snd_soc_card_cht_yb.name =3D SOF_CARD_NAME; + snd_soc_card_cht_yb.driver_name =3D SOF_DRIVER_NAME; + } else { + snd_soc_card_cht_yb.name =3D CARD_NAME; + snd_soc_card_cht_yb.driver_name =3D DRIVER_NAME; + } + + /* register the soc card */ + snd_soc_card_cht_yb.dev =3D &pdev->dev; + ret_val =3D devm_snd_soc_register_card(&pdev->dev, &snd_soc_card_cht_yb); + if (ret_val) { + dev_err(&pdev->dev, + "snd_soc_register_card failed %d\n", ret_val); + return ret_val; + } + platform_set_drvdata(pdev, &snd_soc_card_cht_yb); + + return ret_val; +} + +static struct platform_driver snd_cht_yb_mc_driver =3D { + .driver =3D { + .name =3D "cht-yogabook", + }, + .probe =3D snd_cht_yb_mc_probe, +}; + +module_platform_driver(snd_cht_yb_mc_driver); + +MODULE_DESCRIPTION("Lenovo Yoga Book YB1-X9x machine driver"); +MODULE_AUTHOR("Yauhen Kharuzhy"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:cht-yogabook"); --=20 2.51.0