From nobody Sun Feb 8 07:52:31 2026 Received: from mx0b-001ae601.pphosted.com (mx0b-001ae601.pphosted.com [67.231.152.168]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A9CA332ABEF; Tue, 21 Oct 2025 10:50:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=67.231.152.168 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761043837; cv=fail; b=k1EH6jYIfKxu0sG6bg1aQjn5hpJcNf9mC4hztdxS10AgAju8WPuO8NdE3FO5MSmQ3ngvSQmduM2osf/carZvoSblz2Gfxio25RtSro5ocBi3jn7oHu71m9bXZe1h8RgpShGzd+3IVlcrcZ02uQKfzs5WEZax6jRr7t6yLb98Ekk= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761043837; c=relaxed/simple; bh=4cURmH1QLqQ+5LQ2UeEJVKlvm1mL/aVSIfAqN+RVz+U=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=BEompFLHPHWebOti39CO89g3pr6+aJ1KDK+SUwJNkkidX2dmqX0NzW3oUa0hbrZPlWfSWOZ7FqvzvIfmo7LZVz8/bAmAzOwGp4Jlq/LJCEiOlPVhKGmLVHU7ArcrC6yJ1w8+UlIuWlYyyBh7ALQXa7r4KemFmNNl/rlKnokBook= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=opensource.cirrus.com; spf=pass smtp.mailfrom=opensource.cirrus.com; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b=W2Wb9nbp; dkim=pass (1024-bit key) header.d=cirrus4.onmicrosoft.com header.i=@cirrus4.onmicrosoft.com header.b=JiKBMDH2; arc=fail smtp.client-ip=67.231.152.168 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=opensource.cirrus.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=opensource.cirrus.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="W2Wb9nbp"; dkim=pass (1024-bit key) header.d=cirrus4.onmicrosoft.com header.i=@cirrus4.onmicrosoft.com header.b="JiKBMDH2" Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 59L4xtJo2412958; Tue, 21 Oct 2025 05:50:31 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s= PODMain02222019; bh=JUZrG0RyyF/geI7EqBBDH34ZZ6JaT5yRhMW66pAdCyo=; b= W2Wb9nbpUdqAVyzQIpgJ+obEr1Bm9kA7ujzVXqXcwAj+Ulu7M8IAmKEzzFIhxsY7 LU8XR9KUot75qB8pvi/FNSR0IDCKtEg//gt9ZYqZUiymF1PlO04X9UKeVNbYuF97 wHtB9a4No/I1Mwt55lWouuSOFIuRZEZ5yPCesVxowV1NtyD7jU7nYfsTGFIQg61y nIGNlMQ6dyKNW+LPCb7SL881aq2l7UMVI9yDoGI9/kV2Ypj7+L7zesXQkNSszDlJ W+T8Fi7BW7U/Qvg04hAQtHCFsJ4HHfBnGzChyJQ6D/t+4yqeWSDJ0DLxVozHaWvA DAOw+6f+43B+e9t9u2Hh3w== Received: from ch1pr05cu001.outbound.protection.outlook.com (mail-northcentralusazon11020101.outbound.protection.outlook.com [52.101.193.101]) by mx0b-001ae601.pphosted.com (PPS) with ESMTPS id 49v7aj3eg6-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Tue, 21 Oct 2025 05:50:31 -0500 (CDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=pBOTqRgfkn4FqE57BNvYbi6jAzW/6CzvtOR/mUyVUFvWrxAhuW9tZA/Li1hHNSvJEMq9qR63Zg0e1TOCMFXZ2ICvqTU07QCN6zWPCq2QbZYsI2hrV/Bg1Xa0ys2AFeY9kEPvGJsQ3NF7EM0PKO4a8Hp1opLWApwArnCD7iOrdvOQffWwn03iSnQ1rRVpuxJH8/G4yuLtoQq8tzG18oQwf1vlan07ExjQ/l0qCTBO/cVaQO99YRPiXnDUaZPBw+czBPVcRHMRsmrBTHgpyLAxxp4wkwc1Deit8KErlyWS9uDBpnTSfXgLtvOtm2WlAIFkBVA42/D0xReV6W3KQP4V8w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=JUZrG0RyyF/geI7EqBBDH34ZZ6JaT5yRhMW66pAdCyo=; b=eLxm9gRvyjCOS/1wZgOBGck1Gc/43xkoUMHCGvm7ww7FXFj2vUwxNw2vrfjo8nr4igTcMsBKakMPa3njWxq0WWvNM/MHAzxrbnWbxM4XEe5qJBiddZjQC8iFxoFSm8ok4Mxyxxr/c1PhWP1ZStVHQGyRhE09kERwdXJg6M4MY1qJ3pGXJDWHdg7SK+jWZHPWzfGqp2DMQN28Q9rAPXGkpU3zmnJp/HWRU04dz/3V76R0QYImD08VX9mvIBPifL22TvICQXBaP1cOgj579y5ceblXQKshjn6gvv/M2Zf4MSSHXKl8mWtiagaIYUbqRIX/UbZ60yLfYVxfTWgid0lNew== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=fail (sender ip is 84.19.233.75) smtp.rcpttodomain=cirrus.com smtp.mailfrom=opensource.cirrus.com; dmarc=fail (p=reject sp=reject pct=100) action=oreject header.from=opensource.cirrus.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus4.onmicrosoft.com; s=selector2-cirrus4-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=JUZrG0RyyF/geI7EqBBDH34ZZ6JaT5yRhMW66pAdCyo=; b=JiKBMDH2g8FqUtQXR01HP8TpkB17cUxwpxjSUR4T7pzxEclJ7738Mvc5QDCOCOz2lXfTavzHkNhvsHzYadSHHQdEVvjpMKTV+q6rW4g6kzvxx+25NA0Uj7jREZpcUsoDf0cDeQLbkAle4+bLeb9Fge492MU9rwgv06fkfiN0JUY= Received: from BYAPR06CA0014.namprd06.prod.outlook.com (2603:10b6:a03:d4::27) by CH4PR19MB8682.namprd19.prod.outlook.com (2603:10b6:610:232::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9228.17; Tue, 21 Oct 2025 10:50:25 +0000 Received: from SJ1PEPF000023CC.namprd02.prod.outlook.com (2603:10b6:a03:d4:cafe::cc) by BYAPR06CA0014.outlook.office365.com (2603:10b6:a03:d4::27) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9228.16 via Frontend Transport; Tue, 21 Oct 2025 10:50:24 +0000 X-MS-Exchange-Authentication-Results: spf=fail (sender IP is 84.19.233.75) smtp.mailfrom=opensource.cirrus.com; dkim=none (message not signed) header.d=none;dmarc=fail action=oreject header.from=opensource.cirrus.com; Received-SPF: Fail (protection.outlook.com: domain of opensource.cirrus.com does not designate 84.19.233.75 as permitted sender) receiver=protection.outlook.com; client-ip=84.19.233.75; helo=edirelay1.ad.cirrus.com; Received: from edirelay1.ad.cirrus.com (84.19.233.75) by SJ1PEPF000023CC.mail.protection.outlook.com (10.167.244.6) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9253.7 via Frontend Transport; Tue, 21 Oct 2025 10:50:24 +0000 Received: from ediswmail9.ad.cirrus.com (ediswmail9.ad.cirrus.com [198.61.86.93]) by edirelay1.ad.cirrus.com (Postfix) with ESMTPS id A79C640654B; Tue, 21 Oct 2025 10:50:22 +0000 (UTC) Received: from ediswws06.ad.cirrus.com (ediswws06.ad.cirrus.com [198.90.208.24]) by ediswmail9.ad.cirrus.com (Postfix) with ESMTPSA id 6AE5F822540; Tue, 21 Oct 2025 10:50:22 +0000 (UTC) From: Richard Fitzgerald To: broonie@kernel.org, tiwai@suse.com Cc: linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org, patches@opensource.cirrus.com Subject: [PATCH v2 01/11] ASoC: cs35l56: Read silicon ID during initialization and save it Date: Tue, 21 Oct 2025 11:50:12 +0100 Message-ID: <20251021105022.1013685-2-rf@opensource.cirrus.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251021105022.1013685-1-rf@opensource.cirrus.com> References: <20251021105022.1013685-1-rf@opensource.cirrus.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ1PEPF000023CC:EE_|CH4PR19MB8682:EE_ X-MS-Office365-Filtering-Correlation-Id: 27143e38-0bab-4941-7568-08de108fa38f X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|36860700013|376014|61400799027|82310400026; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?6SoGtK7aHL6CXEZYE1fkEWo/OoDzyFB6yredTrIRwhH6nd9fQbZWR0c+rZC6?= =?us-ascii?Q?qSnKEtW5+MvXbyXxA+TdBIg+MvbHU9P8YfYfnfmTdNiy8naLGsDDnUYl72VL?= =?us-ascii?Q?3CssxOFaGl0HkgA689STS3io8QfJXT7m2JCP0W4ghuYNr3aEWWtWUXTDttGF?= =?us-ascii?Q?NtVO3H9roYojNyx0nnryRj9gOufPaDrI/JHzQ80TkI1vWLiPo3ZY+ndcI3hW?= =?us-ascii?Q?QWT9VRURF5FUUorGAXL6Ba1ZvVapqaVHtnInbGWU7+JpFACEJKKWl/KTrp9t?= =?us-ascii?Q?4kmkwTPnksDHXRMKMqic0JSGogeViT1aBrNZm47IY3ywyaQUWIc1qZ1MfVZ4?= =?us-ascii?Q?3kT4ujk7H5AEtzp6bb0fzjNhWArUQt2M86gqFUPhS+k481IpupDcMt12qFJf?= =?us-ascii?Q?/yI9dzAgZoB2dA/LLgayHt1OqxNFCL6XenhMJikbTMR6sS0DXVjxMomg4iRp?= =?us-ascii?Q?pghCBGzkZFztlg29HeKBHE8ufsg8BMRoxlJmct4po+Q4G8Q3yNCO1iLqbjpS?= =?us-ascii?Q?eKzIp1je64V36Kw5KQIN6s0Mga9RKYRq8PReeLtoQtnjsc7WsoR3ouaCwEfO?= =?us-ascii?Q?c5C57UdhJR7ayP5G3RnLTrVgWGr6boGhLbWJuvm14TgUJA2/8xWJPTfeO4IR?= =?us-ascii?Q?U+QSOXDpcSulFx9qXjAh8S5Mu9bUbNE6j9l3bofwOQ8ODdYJaRTNUmm8ulT3?= =?us-ascii?Q?Fr19YyEaPp79X8uiDLLjGJTb9t+06lLG9ChsgwRp8XR96jACsFfU/DX3r0Lb?= =?us-ascii?Q?6tTqY2iNjVZTScPp8q1zn6/VV1+c3IZwKweJ0qJSnLruo0CECMwoEiBE2Rks?= =?us-ascii?Q?FIVngg4lX8BRgMaNDv1meyCvJBjvcxvKXPVhgtDernw13E7GQ3T0XqkINC3c?= =?us-ascii?Q?AaeyluTlwSnV16+AeAiNYv3Bg2YQuRC/hMta/Pq4lM6eddCa0dvEULiSXyBV?= =?us-ascii?Q?X3XX1vm61rQmd4wubRCj2yk4XP2kEBQbTTuko8nXCi+ixt4aK+MPTDSbTPYO?= =?us-ascii?Q?FfbSiDp7/qOfIQ9PQXan3ILRNyLC7a0s0Dyu5JtVehxJMCV6yx2e8fSD/Y17?= =?us-ascii?Q?aCztwKTwS+oH+3t3ATZcGFjurCewcDlGsf5ynJHNPowDVzQvirq5x4J3ihwb?= =?us-ascii?Q?C0yOtMKovUkPfUf4b8PkJfMNcLQdjXo2PjK2AesHG6uvKktDU8lhzWcscd6G?= =?us-ascii?Q?sIgkyRLS0x5AdsNz4sVDrYD3sFoThGeqbSl5jFT71XKD6pajA3R7iiN9+HdM?= =?us-ascii?Q?M9QQBJySZpFZ+5n2/XTwIkDODK44CEzMIWKBT7ms4jXDI4Q1SKN9Jx5wIEIp?= =?us-ascii?Q?2qEhwHrv1nGCx4H8LPAQ7HvGgJJJ6TOSCTZLxtLhspoahfvo/doXWAQ7GHH7?= =?us-ascii?Q?MLEMpyEbYX10T3j/AcgtN/vOjn+lWBrrb75NH4hsw2K5jGhB38AAq/7BUopM?= =?us-ascii?Q?Qj30b+pmmsHuC0X2KJWrJayprh+xoW4PiledawlZTX/QyYt5yCjWxXhHSaAZ?= =?us-ascii?Q?bePRV+9ziFbM/w9+1WvsMhkVwIrQDLp/k1KjgfhOL+4IvkhmHh9tbK4+N+oT?= =?us-ascii?Q?acnWBYcHNPKcdBZbH0E=3D?= X-Forefront-Antispam-Report: CIP:84.19.233.75;CTRY:GB;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:edirelay1.ad.cirrus.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(36860700013)(376014)(61400799027)(82310400026);DIR:OUT;SFP:1102; X-OriginatorOrg: opensource.cirrus.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Oct 2025 10:50:24.0296 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 27143e38-0bab-4941-7568-08de108fa38f X-MS-Exchange-CrossTenant-Id: bec09025-e5bc-40d1-a355-8e955c307de8 X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=bec09025-e5bc-40d1-a355-8e955c307de8;Ip=[84.19.233.75];Helo=[edirelay1.ad.cirrus.com] X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: TreatMessagesAsInternal-SJ1PEPF000023CC.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CH4PR19MB8682 X-Proofpoint-ORIG-GUID: FfYXc0979ZW0pfmkLW7MWYVoPkQaDI4t X-Proofpoint-GUID: FfYXc0979ZW0pfmkLW7MWYVoPkQaDI4t X-Authority-Analysis: v=2.4 cv=bdNmkePB c=1 sm=1 tr=0 ts=68f76577 cx=c_pps a=IAlGFxvWO5AZskdmYTP3vQ==:117 a=h1hSm8JtM9GN1ddwPAif2w==:17 a=6eWqkTHjU83fiwn7nKZWdM+Sl24=:19 a=z/mQ4Ysz8XfWz/Q5cLBRGdckG28=:19 a=x6icFKpwvdMA:10 a=s63m1ICgrNkA:10 a=RWc_ulEos4gA:10 a=VkNPw1HP01LnGYTKEx00:22 a=w1d2syhTAAAA:8 a=nj95HRKCm9CT-uqgyqgA:9 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMDIxMDA4NSBTYWx0ZWRfX8tX0THmo2W0X 1BrICiHVqA4kuS5/JcK0e8ymoO5o3xKY1W5IYjiATYYoqNHEfW0cLUzvuG+g0y+h7zctDUQUgxZ 1wFR7Dtj0DvV6w/wfc+A71QkNg/rhDwvBhz+sOsUipNLua7eV0e6/gUFogYIJ8lbuTdpLgF+s73 5/J6nvXhAuAavyOA8K74n9Ln+I4lbNJ5zckoTAuZZfSQn+l1WVvVfuYLEUvLowoDWFTMwK9ZyzD O8HPRGo1HRU1CF/ai6FUrMAOw+pXz9louzqoNDHxTyrtfKO8c6aXmcn29TR/v/P70AbTN7FXGSQ uK8xhUpPT3BgAaZb0phze2EmjoW9E3Yy5xPR/d6ZID2V4r4yD71TBi6IRUFsRc9sU7sPDxhEkih IUJ6gOGX8SNEExwBzFUk7Lw52+mu1g== X-Proofpoint-Spam-Reason: safe Content-Type: text/plain; charset="utf-8" Read the silicon ID from the amp during one-time cs35l56_hw_init() and store it in struct cs35l56_base, instead of reading it from registers every time it is needed. Note that marking it non-volatile without a default in regmap isn't a suitable alternative because this causes regcache_sync() to always write the cached value out to the registers. This could trigger a bus fault interrupt inside the amp, which we want to avoid. Signed-off-by: Richard Fitzgerald Reviewed-by: Takashi Iwai --- No changes since V1. include/sound/cs35l56.h | 1 + sound/soc/codecs/cs35l56-shared.c | 53 +++++++++++++++---------------- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/include/sound/cs35l56.h b/include/sound/cs35l56.h index ab044ce2aa8b..ec9b1072d6be 100644 --- a/include/sound/cs35l56.h +++ b/include/sound/cs35l56.h @@ -309,6 +309,7 @@ struct cs35l56_base { struct cs35l56_spi_payload *spi_payload_buf; const struct cs35l56_fw_reg *fw_reg; const struct cirrus_amp_cal_controls *calibration_controls; + u64 silicon_uid; }; =20 static inline bool cs35l56_is_otp_register(unsigned int reg) diff --git a/sound/soc/codecs/cs35l56-shared.c b/sound/soc/codecs/cs35l56-s= hared.c index 9e6b9ca2f354..1ecfc38d8eb4 100644 --- a/sound/soc/codecs/cs35l56-shared.c +++ b/sound/soc/codecs/cs35l56-shared.c @@ -853,7 +853,7 @@ struct cs35l56_pte { } __packed; static_assert((sizeof(struct cs35l56_pte) % sizeof(u32)) =3D=3D 0); =20 -static int cs35l56_read_silicon_uid(struct cs35l56_base *cs35l56_base, u64= *uid) +static int cs35l56_read_silicon_uid(struct cs35l56_base *cs35l56_base) { struct cs35l56_pte pte; u64 unique_id; @@ -870,14 +870,15 @@ static int cs35l56_read_silicon_uid(struct cs35l56_ba= se *cs35l56_base, u64 *uid) unique_id |=3D (u32)pte.x | ((u32)pte.y << 8) | ((u32)pte.wafer_id << 16)= | ((u32)pte.dvs << 24); =20 - *uid =3D unique_id; + cs35l56_base->silicon_uid =3D unique_id; =20 return 0; } =20 -static int cs35l63_read_silicon_uid(struct cs35l56_base *cs35l56_base, u64= *uid) +static int cs35l63_read_silicon_uid(struct cs35l56_base *cs35l56_base) { u32 tmp[2]; + u64 unique_id; int ret; =20 ret =3D regmap_bulk_read(cs35l56_base->regmap, CS35L56_DIE_STS1, tmp, ARR= AY_SIZE(tmp)); @@ -886,9 +887,11 @@ static int cs35l63_read_silicon_uid(struct cs35l56_bas= e *cs35l56_base, u64 *uid) return ret; } =20 - *uid =3D tmp[1]; - *uid <<=3D 32; - *uid |=3D tmp[0]; + unique_id =3D tmp[1]; + unique_id <<=3D 32; + unique_id |=3D tmp[0]; + + cs35l56_base->silicon_uid =3D unique_id; =20 return 0; } @@ -915,33 +918,14 @@ static const struct cirrus_amp_cal_controls cs35l63_c= alibration_controls =3D { =20 int cs35l56_get_calibration(struct cs35l56_base *cs35l56_base) { - u64 silicon_uid =3D 0; int ret; =20 /* Driver can't apply calibration to a secured part, so skip */ if (cs35l56_base->secured) return 0; =20 - switch (cs35l56_base->type) { - case 0x54: - case 0x56: - case 0x57: - ret =3D cs35l56_read_silicon_uid(cs35l56_base, &silicon_uid); - break; - case 0x63: - ret =3D cs35l63_read_silicon_uid(cs35l56_base, &silicon_uid); - break; - default: - ret =3D -ENODEV; - break; - } - - if (ret < 0) - return ret; - - dev_dbg(cs35l56_base->dev, "UniqueID =3D %#llx\n", silicon_uid); - - ret =3D cs_amp_get_efi_calibration_data(cs35l56_base->dev, silicon_uid, + ret =3D cs_amp_get_efi_calibration_data(cs35l56_base->dev, + cs35l56_base->silicon_uid, cs35l56_base->cal_index, &cs35l56_base->cal_data); =20 @@ -1111,6 +1095,21 @@ int cs35l56_hw_init(struct cs35l56_base *cs35l56_bas= e) CS35L56_TEMP_ERR_EINT1_MASK, 0); =20 + switch (cs35l56_base->type) { + case 0x54: + case 0x56: + case 0x57: + ret =3D cs35l56_read_silicon_uid(cs35l56_base); + break; + default: + ret =3D cs35l63_read_silicon_uid(cs35l56_base); + break; + } + if (ret) + return ret; + + dev_dbg(cs35l56_base->dev, "SiliconID =3D %#llx\n", cs35l56_base->silicon= _uid); + return 0; } EXPORT_SYMBOL_NS_GPL(cs35l56_hw_init, "SND_SOC_CS35L56_SHARED"); --=20 2.47.3 From nobody Sun Feb 8 07:52:31 2026 Received: from mx0b-001ae601.pphosted.com (mx0b-001ae601.pphosted.com [67.231.152.168]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D33782E8B8A; Tue, 21 Oct 2025 10:50:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=67.231.152.168 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761043835; cv=fail; b=HX4TGvxx6SsHX352yelmlgAkqpfyelJcONJJuqVRLET+YNb1WOmMcjLO6t55EvFh91zTStrwaL8TRVD1xYz2XwGJBnEwqd8HQ/YGcdzmXtMG70VzbVyxFX2j4QJoKlUxj68F/dMQOB/0oAG5rwiUFTUxri2K9FRy/Zn9xaN5CgI= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761043835; c=relaxed/simple; bh=8K43xn8jdweY6TXEWUlkz8HS77zoj/g5sp9WQyoCWPY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=d5BXIplYzXrlUqVkpJLM3lMz5My2PJL/9YIVuF3JWhl+h+vkbqVmbzDUUOBCybt7WiRdxbXMMAELPr2s5hZi39Z+zONhBJo8T3U6gtAbaWnPbYRvlr7BzrjrtYjH/Tp8ENagCvBLqfo4JGiEXV0nvoG71Wt+1c1g10NiXUVmzFY= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=opensource.cirrus.com; spf=pass smtp.mailfrom=opensource.cirrus.com; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b=ndd5o2py; dkim=pass (1024-bit key) header.d=cirrus4.onmicrosoft.com header.i=@cirrus4.onmicrosoft.com header.b=wCcKujXL; arc=fail smtp.client-ip=67.231.152.168 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=opensource.cirrus.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=opensource.cirrus.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="ndd5o2py"; dkim=pass (1024-bit key) header.d=cirrus4.onmicrosoft.com header.i=@cirrus4.onmicrosoft.com header.b="wCcKujXL" Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 59LASk2D2958765; Tue, 21 Oct 2025 05:50:29 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s= PODMain02222019; bh=8qkO8xrDNtbPkK9AVAg/dkUPEQzfq1UDS5jPOxB5yGQ=; b= ndd5o2pyxb4fxKnmdjyygVESZqSm2UonUxHx9zv0rfXaGzHefg+DV9o85ulqXmjp WTOaZGivkCYpz4bxBrhABBiD2D9mY8/u2ixS9QUYtmS3gBfZPkTAJX1DIsiFNyOD R0x/qCF90OsA7vepLUdi9gAKy5/xaqM7FR0g+jJ49Zl/t6lmhuMBoPrVrHer8BqQ xn+UAHi9aW3JctE14HUz+7znZSDKYYh0TcGZ+p7uxwq0QyalscfX3CJ5aACBUzSD Ht2y2Ss45FGrAOI1FVmYKkedkSEklz9u+qf1XFJlRcPVaSM91KCu6Hnt59/vdGuF szx57XpQ++R+v+yYjFjhGw== Received: from ph7pr06cu001.outbound.protection.outlook.com (mail-westus3azon11020136.outbound.protection.outlook.com [52.101.201.136]) by mx0b-001ae601.pphosted.com (PPS) with ESMTPS id 49v7aj3efx-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Tue, 21 Oct 2025 05:50:29 -0500 (CDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=wn7akZT7I9d0NkGrsTrlHR3J6SlWSmXqGSvVoOtjD0PHzgJPuloqbT9Dd2WHppbrbl/NA6M31woA5qHGF3NE+h9V849hw3HQ18odiJf0+SHtAm/0tHHrnwY5+dtWDCDoYQifcJupfdJvITNw+E20+qgEQ6QIfk3kFKhc873hK8S+XD0gK6zJPqwZbkJJ8AWk2KYE/sUmH8Aj6qZoocRkuqfam7iitIoGx6/Sln+VVqgEbCVY0pWYbkBz7uub2HorSBq1/YH1Zf3Z/Hw6+XL1nrUwPxT1bf6ssIuQ5PAqRcxu0W5AU8jVxIQOvdRgTXprD9TJyLYDZJIEx+5pCGgHEg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=8qkO8xrDNtbPkK9AVAg/dkUPEQzfq1UDS5jPOxB5yGQ=; b=EEbk/FUrgSTcPIs1cPA6ZIinWnb98A3LExZv0zi6/UNWsOosaHeS5mm0Q1AoWmbUCN5IB+JD1MKb9qTAz8lvsiMzXD3dmWYfUch2vtgia2oOyAYHrTij4P4I9+3BV+XozE+1QyB0aslHYiM9CspcNMNIo2JSYY2dbkew3McQpoAPhOO9GMxF9XCICd+qj8JaEPG/jrFo0xjv8qYNkJ1xAxmVo9slkoSp9u3FqG7HvmMOu/tKCjz4e9uZWc8fKiWjXMH5sGKP+hh4qFvu2cL3EJd2HR+eEI6u2mtoC9rd1Vo+6PGDE+8MTAgjGYonkJOTCQs99RDnHXESbW78QES4BQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=fail (sender ip is 84.19.233.75) smtp.rcpttodomain=cirrus.com smtp.mailfrom=opensource.cirrus.com; dmarc=fail (p=reject sp=reject pct=100) action=oreject header.from=opensource.cirrus.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus4.onmicrosoft.com; s=selector2-cirrus4-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=8qkO8xrDNtbPkK9AVAg/dkUPEQzfq1UDS5jPOxB5yGQ=; b=wCcKujXL/2zb1ntwPOl9PDDGjmNSFjFqh1eichw+XxhhklSWHdwHqFVDMKQSP6oP0+cbcx+gBiMSZx+EiJNnWOMTiN1KFFJCkTTdH/TQKE/U3YI2U7vCDbWPP6pvJzDqsomYQtljSbFpoR9uueNOJ63ibWQ5DdEI+QUQYQLljzk= Received: from MN2PR01CA0046.prod.exchangelabs.com (2603:10b6:208:23f::15) by LV3PR19MB8513.namprd19.prod.outlook.com (2603:10b6:408:1b9::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9253.12; Tue, 21 Oct 2025 10:50:25 +0000 Received: from BL02EPF0001A0FD.namprd03.prod.outlook.com (2603:10b6:208:23f:cafe::a5) by MN2PR01CA0046.outlook.office365.com (2603:10b6:208:23f::15) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9228.16 via Frontend Transport; Tue, 21 Oct 2025 10:50:32 +0000 X-MS-Exchange-Authentication-Results: spf=fail (sender IP is 84.19.233.75) smtp.mailfrom=opensource.cirrus.com; dkim=none (message not signed) header.d=none;dmarc=fail action=oreject header.from=opensource.cirrus.com; Received-SPF: Fail (protection.outlook.com: domain of opensource.cirrus.com does not designate 84.19.233.75 as permitted sender) receiver=protection.outlook.com; client-ip=84.19.233.75; helo=edirelay1.ad.cirrus.com; Received: from edirelay1.ad.cirrus.com (84.19.233.75) by BL02EPF0001A0FD.mail.protection.outlook.com (10.167.242.104) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9253.7 via Frontend Transport; Tue, 21 Oct 2025 10:50:23 +0000 Received: from ediswmail9.ad.cirrus.com (ediswmail9.ad.cirrus.com [198.61.86.93]) by edirelay1.ad.cirrus.com (Postfix) with ESMTPS id ABF4D406552; Tue, 21 Oct 2025 10:50:22 +0000 (UTC) Received: from ediswws06.ad.cirrus.com (ediswws06.ad.cirrus.com [198.90.208.24]) by ediswmail9.ad.cirrus.com (Postfix) with ESMTPSA id 6DB63822541; Tue, 21 Oct 2025 10:50:22 +0000 (UTC) From: Richard Fitzgerald To: broonie@kernel.org, tiwai@suse.com Cc: linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org, patches@opensource.cirrus.com Subject: [PATCH v2 02/11] ASoC: cs-amp-lib: Add helpers for factory calibration Date: Tue, 21 Oct 2025 11:50:13 +0100 Message-ID: <20251021105022.1013685-3-rf@opensource.cirrus.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251021105022.1013685-1-rf@opensource.cirrus.com> References: <20251021105022.1013685-1-rf@opensource.cirrus.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BL02EPF0001A0FD:EE_|LV3PR19MB8513:EE_ X-MS-Office365-Filtering-Correlation-Id: bea453f3-757f-4276-40f0-08de108fa364 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|82310400026|61400799027|36860700013; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?PR8fnac7RRUooroF+2wmbbfVf2TROIXVq85t3p52ifN5rAzc75xTOsCbzgXZ?= =?us-ascii?Q?MB8b1jSjwvz9njDETRmqpAjOJiYq+xQxoQ0aIkaTa7/vJis2oYRVedDQlMEP?= =?us-ascii?Q?oC84/Xn+Bw/5id6f6VeqECUR/GK3I5UpfhE+64s7q0hccCRZh9QiQfX7S7WB?= =?us-ascii?Q?iKY4WAeo9C9PQKJ+mHJS71UO0VNAcipItZnEna+cwQutYDZaXMgL7qSm3Noo?= =?us-ascii?Q?CiefmeplRZ+jMFmv/yls9mRkukJ8jeInFmuheLspwpXLgDNSwEPEUpy6+0vE?= =?us-ascii?Q?k6FZvhk5aifqISXGS1vM/CqreTeE1/IwK0qfsB5TFCBacFdoTTzZWbErypc1?= =?us-ascii?Q?NUDgoO61W3W3xNr+9jUpv5noD90SWfnSDJtVe5kUWzOMStKEv3XSsakhNCsk?= =?us-ascii?Q?Zge2mXFiRqAVB9zgXYFBBXQgarju2NbVDrJ9b02QCA2h1ApC/yxZLjHXJlwN?= =?us-ascii?Q?706c9IINY/gTLk+lGQPw2NoTSxqxXSdBZFjINRr/c7tt1f0mQPEI8Nrr5mE0?= =?us-ascii?Q?ZS+xgkANrHssDFXM5tarV77mHb3ItSmXu0LsJTyrBWwJAeQN7HdO5b6egLd+?= =?us-ascii?Q?VWNIdV0zJkdERiUuEb8ZkRvB7f2pIr0LqSSEZyAJNTBbgdj2OC8TT9PlKycQ?= =?us-ascii?Q?LkGPpH/vccLf42RvST6K2EsD2T/NpHv21QRTIyc1T+JS74lsMdcL6YzF3fYS?= =?us-ascii?Q?GNmgyHF22etgp8r70EUMxVl2Qqy/6kzOAqjFeiG5ZVZ4pl8TNE3kNile/9Ye?= =?us-ascii?Q?pFVM2hd+gAEfMl2NE8xRrDpWnm9R4d/htOxV4x2ytxKrJPGquBxTsRl6vLlb?= =?us-ascii?Q?R3iE+NQH4lWfhjXBb9Rz0GwZ+ltLitWaZPt52egnYVcpCRAYo5qpck2IE6bu?= =?us-ascii?Q?ttHTUyQBJcUI6rZnvVX8nRLkrTojwWYhCWDnGd5gHwNdQI5fmN1fxvOA+nus?= =?us-ascii?Q?2rCdyW2ZavxO0WYuZzUqBIbkhLufcCArrhhF0TrpCyfD6hhnvIT95aM23u41?= =?us-ascii?Q?o0nDxxklRxSDmB9Rbfyj70crj46dqyPZnaYE0hF0uinnwrXjUZb7O31PwDLe?= =?us-ascii?Q?bGLxzue9NSdtK0PaQ1hUqKVDjufWEYDN6sYddSPofykQW3a7xPvf9LugA3u8?= =?us-ascii?Q?QZIZOVziMq6cHubXU7Ft1Xkmvx6UPXoulKnTkmIo1dugrStXiwK1aCX71RE9?= =?us-ascii?Q?PCijD9wQIlVE94KiXzrqmt1rIek+qxcTcrenl9ZOKgv8j963Ew9Hmr/ACdKE?= =?us-ascii?Q?VQMvY3jWZGXQd2yTe6KTkBD7UWFJZ5iOQa9Qj0rXsZHtZVnaqer6DtLsqhjo?= =?us-ascii?Q?4b1lcaNn+4u3XxG0IhDQOeM1UsEWaFXpojus3vmmQmHblFQfcLExDvfi/9Lh?= =?us-ascii?Q?zUrIioWnxLWuXxiNbkAG1ua37yhSG5sBNl8W8qSPbF33jGMcnXQAWbzzhRLG?= =?us-ascii?Q?DB9wUWzIomUSxUANsfhj14LXuvS4G6vh+UBydMymPS6PyFAxjTFlVAFhBZ2t?= =?us-ascii?Q?G4XZBM27lxkaA+PWM0LK7bcJe80Ss6yToZ3C7DYg1uRNwaNRt5KdIgiX9+y+?= =?us-ascii?Q?nbr4Y7Let2ACOCZndqE=3D?= X-Forefront-Antispam-Report: CIP:84.19.233.75;CTRY:GB;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:edirelay1.ad.cirrus.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(376014)(82310400026)(61400799027)(36860700013);DIR:OUT;SFP:1102; X-OriginatorOrg: opensource.cirrus.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Oct 2025 10:50:23.8750 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: bea453f3-757f-4276-40f0-08de108fa364 X-MS-Exchange-CrossTenant-Id: bec09025-e5bc-40d1-a355-8e955c307de8 X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=bec09025-e5bc-40d1-a355-8e955c307de8;Ip=[84.19.233.75];Helo=[edirelay1.ad.cirrus.com] X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: TreatMessagesAsInternal-BL02EPF0001A0FD.namprd03.prod.outlook.com X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: LV3PR19MB8513 X-Proofpoint-ORIG-GUID: ZYO53NlZ7CsEzNQSqLKRr6C9LseiHZ3t X-Proofpoint-GUID: ZYO53NlZ7CsEzNQSqLKRr6C9LseiHZ3t X-Authority-Analysis: v=2.4 cv=bdNmkePB c=1 sm=1 tr=0 ts=68f76575 cx=c_pps a=SjKxu3n00dGHhKqS4WZ18w==:117 a=h1hSm8JtM9GN1ddwPAif2w==:17 a=6eWqkTHjU83fiwn7nKZWdM+Sl24=:19 a=z/mQ4Ysz8XfWz/Q5cLBRGdckG28=:19 a=x6icFKpwvdMA:10 a=s63m1ICgrNkA:10 a=RWc_ulEos4gA:10 a=VkNPw1HP01LnGYTKEx00:22 a=w1d2syhTAAAA:8 a=9fJfBgaK4NS20Kq2ylQA:9 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMDIxMDA4NSBTYWx0ZWRfXzAS91ASObWhU TKAdzOC+vtBToluo5eD5R7TkClSo3XDdyymr8foESja3T00TMfDh6oCAaeEMlrbhO1p9N9kzQfd Phj57iSaORFs7bkMnw0pwfv1iOdGkbFSyavXaVtZaAjXYDThE/SXMngBV87iXeuhEQ42PJChQx3 5+mmB/9tozvvPvU6odf6SnQ8jTfDrDjEJDP68wW62SrVyUNZORTsp5lVTdnunB8XDENhJKeaPMe 6Mh/Zcq5CC964cEaVKW4fqKOF9x41nTknvByuWAQU+qbymcSz5ibRqUKDXHVgxviLvdnJpIix9O YgfKwTeLWtIAASLO+7e4LUMvcLtQClUP6IDAlzI/X9SZEymHZDva4+dg81fgtCnozMFBWn+E0xx gySTby69TK8mlLD54UdERxGYPge+HA== X-Proofpoint-Spam-Reason: safe Content-Type: text/plain; charset="utf-8" Add helper functions for performing factory calibration. cs_amp_read_cal_coeffs() reads the results of a calibration into a struct cirrus_amp_cal_data. The calTime member is also filled in with the current time (which is defined to be in Windows format). cs_amp_write_ambient_temp() writes a given temperature value to the firmware control for ambient temperature. The cs_amp_cal_target_u64() has been moved into the header file so that it can be used by the calling code and by KUnit tests. cs_amp_create_debugfs() creates a debugfs directory to contain debugfs files related to calibration. This is placed in a directory in debugfs root, named "cirrus_logic". The purpose of this is to make it easier for tooling to find the files it needs by keeping control of the layout under this directory. By contrast the ASoC debugfs can vary between kernel releases and doesn't have a strictly stable naming convention. HDA does not have a debugfs directory at all and enabling the general ALSA debugfs (which is normally disabled) has other side-effects. Signed-off-by: Richard Fitzgerald Reviewed-by: Takashi Iwai --- Changes in V2: - Added cs_amp_create_debugfs() include/sound/cs-amp-lib.h | 12 +++ sound/soc/codecs/cs-amp-lib.c | 148 ++++++++++++++++++++++++++++++++-- 2 files changed, 155 insertions(+), 5 deletions(-) diff --git a/include/sound/cs-amp-lib.h b/include/sound/cs-amp-lib.h index 43a87a39110c..5b094f8e8a6f 100644 --- a/include/sound/cs-amp-lib.h +++ b/include/sound/cs-amp-lib.h @@ -47,9 +47,21 @@ struct cirrus_amp_cal_controls { int cs_amp_write_cal_coeffs(struct cs_dsp *dsp, const struct cirrus_amp_cal_controls *controls, const struct cirrus_amp_cal_data *data); +int cs_amp_read_cal_coeffs(struct cs_dsp *dsp, + const struct cirrus_amp_cal_controls *controls, + struct cirrus_amp_cal_data *data); +int cs_amp_write_ambient_temp(struct cs_dsp *dsp, + const struct cirrus_amp_cal_controls *controls, + u32 temp); int cs_amp_get_efi_calibration_data(struct device *dev, u64 target_uid, in= t amp_index, struct cirrus_amp_cal_data *out_data); int cs_amp_get_vendor_spkid(struct device *dev); +struct dentry *cs_amp_create_debugfs(struct device *dev); + +static inline u64 cs_amp_cal_target_u64(const struct cirrus_amp_cal_data *= data) +{ + return ((u64)data->calTarget[1] << 32) | data->calTarget[0]; +} =20 struct cs_amp_test_hooks { efi_status_t (*get_efi_variable)(efi_char16_t *name, diff --git a/sound/soc/codecs/cs-amp-lib.c b/sound/soc/codecs/cs-amp-lib.c index 8434d5196107..f9d5c4adf3f2 100644 --- a/sound/soc/codecs/cs-amp-lib.c +++ b/sound/soc/codecs/cs-amp-lib.c @@ -7,12 +7,15 @@ =20 #include #include +#include #include #include #include +#include #include #include #include +#include #include #include =20 @@ -46,6 +49,16 @@ static const struct cs_amp_lib_cal_efivar { }, }; =20 +/* Offset from Unix time to Windows time (100ns since 1 Jan 1601) */ +#define UNIX_TIME_TO_WINDOWS_TIME_OFFSET 116444736000000000ULL + +static u64 cs_amp_time_now_in_windows_time(void) +{ + u64 time_in_100ns =3D div_u64(ktime_get_real_ns(), 100); + + return time_in_100ns + UNIX_TIME_TO_WINDOWS_TIME_OFFSET; +} + static int cs_amp_write_cal_coeff(struct cs_dsp *dsp, const struct cirrus_amp_cal_controls *controls, const char *ctl_name, u32 val) @@ -73,6 +86,34 @@ static int cs_amp_write_cal_coeff(struct cs_dsp *dsp, return -ENODEV; } =20 +static int cs_amp_read_cal_coeff(struct cs_dsp *dsp, + const struct cirrus_amp_cal_controls *controls, + const char *ctl_name, u32 *val) +{ + struct cs_dsp_coeff_ctl *cs_ctl; + __be32 beval; + int ret; + + KUNIT_STATIC_STUB_REDIRECT(cs_amp_read_cal_coeff, dsp, controls, ctl_name= , val); + + if (!IS_REACHABLE(CONFIG_FW_CS_DSP)) + return -ENODEV; + + scoped_guard(mutex, &dsp->pwr_lock) { + cs_ctl =3D cs_dsp_get_ctl(dsp, ctl_name, controls->mem_region, controls-= >alg_id); + ret =3D cs_dsp_coeff_read_ctrl(cs_ctl, 0, &beval, sizeof(beval)); + } + + if (ret < 0) { + dev_err(dsp->dev, "Failed to write to '%s': %d\n", ctl_name, ret); + return ret; + } + + *val =3D be32_to_cpu(beval); + + return 0; +} + static int _cs_amp_write_cal_coeffs(struct cs_dsp *dsp, const struct cirrus_amp_cal_controls *controls, const struct cirrus_amp_cal_data *data) @@ -106,6 +147,45 @@ static int _cs_amp_write_cal_coeffs(struct cs_dsp *dsp, return 0; } =20 +static int _cs_amp_read_cal_coeffs(struct cs_dsp *dsp, + const struct cirrus_amp_cal_controls *controls, + struct cirrus_amp_cal_data *data) +{ + u64 time; + u32 val; + int ret; + + if (list_empty(&dsp->ctl_list)) { + dev_info(dsp->dev, "Calibration disabled due to missing firmware control= s\n"); + return -ENOENT; + } + + ret =3D cs_amp_read_cal_coeff(dsp, controls, controls->ambient, &val); + if (ret) + return ret; + + data->calAmbient =3D (s8)val; + + ret =3D cs_amp_read_cal_coeff(dsp, controls, controls->calr, &val); + if (ret) + return ret; + + data->calR =3D (u16)val; + + ret =3D cs_amp_read_cal_coeff(dsp, controls, controls->status, &val); + if (ret) + return ret; + + data->calStatus =3D (u8)val; + + /* Fill in timestamp */ + time =3D cs_amp_time_now_in_windows_time(); + data->calTime[0] =3D (u32)time; + data->calTime[1] =3D (u32)(time >> 32); + + return 0; +} + /** * cs_amp_write_cal_coeffs - Write calibration data to firmware controls. * @dsp: Pointer to struct cs_dsp. @@ -125,6 +205,44 @@ int cs_amp_write_cal_coeffs(struct cs_dsp *dsp, } EXPORT_SYMBOL_NS_GPL(cs_amp_write_cal_coeffs, "SND_SOC_CS_AMP_LIB"); =20 +/** + * cs_amp_read_cal_coeffs - Read calibration data from firmware controls. + * @dsp: Pointer to struct cs_dsp. + * @controls: Pointer to definition of firmware controls to be read. + * @data: Pointer to calibration data where results will be written. + * + * Returns: 0 on success, else negative error value. + */ +int cs_amp_read_cal_coeffs(struct cs_dsp *dsp, + const struct cirrus_amp_cal_controls *controls, + struct cirrus_amp_cal_data *data) +{ + if (IS_REACHABLE(CONFIG_FW_CS_DSP) || IS_ENABLED(CONFIG_SND_SOC_CS_AMP_LI= B_TEST)) + return _cs_amp_read_cal_coeffs(dsp, controls, data); + else + return -ENODEV; +} +EXPORT_SYMBOL_NS_GPL(cs_amp_read_cal_coeffs, "SND_SOC_CS_AMP_LIB"); + +/** + * cs_amp_write_ambient_temp - write value to calibration ambient temperat= ure + * @dsp: Pointer to struct cs_dsp. + * @controls: Pointer to definition of firmware controls to be read. + * @temp: Temperature in degrees celcius. + * + * Returns: 0 on success, else negative error value. + */ +int cs_amp_write_ambient_temp(struct cs_dsp *dsp, + const struct cirrus_amp_cal_controls *controls, + u32 temp) +{ + if (IS_REACHABLE(CONFIG_FW_CS_DSP) || IS_ENABLED(CONFIG_SND_SOC_CS_AMP_LI= B_TEST)) + return cs_amp_write_cal_coeff(dsp, controls, controls->ambient, temp); + else + return -ENODEV; +} +EXPORT_SYMBOL_NS_GPL(cs_amp_write_ambient_temp, "SND_SOC_CS_AMP_LIB"); + static efi_status_t cs_amp_get_efi_variable(efi_char16_t *name, efi_guid_t *guid, unsigned long *size, @@ -215,11 +333,6 @@ static struct cirrus_amp_efi_data *cs_amp_get_cal_efi_= buffer(struct device *dev) return ERR_PTR(ret); } =20 -static u64 cs_amp_cal_target_u64(const struct cirrus_amp_cal_data *data) -{ - return ((u64)data->calTarget[1] << 32) | data->calTarget[0]; -} - static int _cs_amp_get_efi_calibration_data(struct device *dev, u64 target= _uid, int amp_index, struct cirrus_amp_cal_data *out_data) { @@ -400,6 +513,31 @@ int cs_amp_get_vendor_spkid(struct device *dev) } EXPORT_SYMBOL_NS_GPL(cs_amp_get_vendor_spkid, "SND_SOC_CS_AMP_LIB"); =20 +/** + * cs_amp_create_debugfs - create a debugfs directory for a device + * + * @dev: pointer to struct device + * + * Creates a node under "cirrus_logic" in the root of the debugfs filesyst= em. + * This is for Cirrus-specific debugfs functionality to be grouped in a + * defined way, independently of the debugfs provided by ALSA/ASoC. + * The general ALSA/ASoC debugfs may not be enabled, and does not necessar= ily + * have a stable layout or naming convention. + * + * Return: Pointer to the dentry for the created directory, or -ENODEV. + */ +struct dentry *cs_amp_create_debugfs(struct device *dev) +{ + struct dentry *dir; + + dir =3D debugfs_lookup("cirrus_logic", NULL); + if (!dir) + dir =3D debugfs_create_dir("cirrus_logic", NULL); + + return debugfs_create_dir(dev_name(dev), dir); +} +EXPORT_SYMBOL_NS_GPL(cs_amp_create_debugfs, "SND_SOC_CS_AMP_LIB"); + static const struct cs_amp_test_hooks cs_amp_test_hook_ptrs =3D { .get_efi_variable =3D cs_amp_get_efi_variable, .write_cal_coeff =3D cs_amp_write_cal_coeff, --=20 2.47.3 From nobody Sun Feb 8 07:52:31 2026 Received: from mx0b-001ae601.pphosted.com (mx0b-001ae601.pphosted.com [67.231.152.168]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C265E32C935; Tue, 21 Oct 2025 10:50:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=67.231.152.168 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761043839; cv=fail; b=lVN8BNGXIflOL89QyfAKbH3epWgRtZ7ubU/YT/VWEYuOeHnBIsBCXXH9T4d7ll/3vKgsFhjaBQe91y9KK53b8s2eC2ArQHvryhXGnmDkQIlHQ5sWtB6fmC/4MSfLNRtIsZBQeBhcbY36zas/i/i1imA6wvyNnRmwZbN5SS95M24= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761043839; c=relaxed/simple; bh=nipDsDkuk1QvDFyL42evDMtR2DmL03RSUWvc1B0X/IQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=WIkDMPReofJPEGLYmuTXix6yqUHURq1bFaHk9sr6ZiQHowBucDAON9MxNZn3fyRtL7WeLbFwOT/TENb7JJzdtH/1m1GCty7rA8aINnqlOUcvEyh0wDzVDtIa2ETz+YH8Kb32HV438Q/3a/kV0D8VY+IdBh2lNNO2Y+fu6ZfQ2sk= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=opensource.cirrus.com; spf=pass smtp.mailfrom=opensource.cirrus.com; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b=BTNR2jSM; dkim=pass (1024-bit key) header.d=cirrus4.onmicrosoft.com header.i=@cirrus4.onmicrosoft.com header.b=ym4Z/yg2; arc=fail smtp.client-ip=67.231.152.168 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=opensource.cirrus.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=opensource.cirrus.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="BTNR2jSM"; dkim=pass (1024-bit key) header.d=cirrus4.onmicrosoft.com header.i=@cirrus4.onmicrosoft.com header.b="ym4Z/yg2" Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 59L9021r941361; Tue, 21 Oct 2025 05:50:32 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s= PODMain02222019; bh=W/2VS7P03zRrZVR2i2nKw5NrfvIPu/CruEGB6xUCfbE=; b= BTNR2jSMUODGfEG60sqMbSxJK1oNj+a7ZkkhfohFjPhpOkqUBzTwYOrMfPsF96RB PCcwYPV6HETRBeUq8KfDBh/vqKwCWoVLKpomez80kqWPODZSWhGvQYHpfte/2KJK vR9zTtketcMyOk1+sNCCd5mmFZMPul2lLvsTqaE3fH0NAS1kpaCb/ASmziYAN7zR bjZRHoucVG6ADqgMjsEDWD+ocOVom379LwZfkgyJ2urZzdai+xjIZ+dAr4YF1M8B 2PUjx9qrqXgGXIKGnrWmBud5B8RexWXO4DqBo1cl34PBNN8RCgFuxdrmZhAhFSze L2j7CRurV1UGg3ONDI5q2Q== Received: from bl2pr02cu003.outbound.protection.outlook.com (mail-eastusazon11021090.outbound.protection.outlook.com [52.101.52.90]) by mx0b-001ae601.pphosted.com (PPS) with ESMTPS id 49v7aj3eg5-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Tue, 21 Oct 2025 05:50:31 -0500 (CDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=wlInu4GHVOfHaSQVPkuSOO4Zh3KqkegE611s97o5ZlkuAd9o5QkXD7OxJJw4w10Ic35BKo48gsODW00BHdXEhTJ17/ZG7r0uRdR88yOvSP6yITIEB51fFJPaFmmVIx7RXhQTepBmMo3w7B0/MVfw5yvJftlabGzXS7uALgn5VlUvzfL5axKf3IQsrSLA6gG1k6hyijNE60nsMiDe5QBC6dR1Blad9ZePm61z5DbbAT49zFUqiFq9ZIshl6rSN58KtePW2vO+3uG0bt51bSna4hlroE/fawwRGzj5LvUuk2a7ZM4CpgTkakf7dG/5agRC2e8G+/xbICfzPGt58iJ3wQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=W/2VS7P03zRrZVR2i2nKw5NrfvIPu/CruEGB6xUCfbE=; b=fY7iVxUPY3yVk6NAV11hKpQcLePizdJ2VUkzlxD1G3u39/YeiEJKLNrDU2IhxNIlSMdZKapVSohT/0sio4B1s1NKEV86RRyqOAaOojHsht8yTgKSf+M2EpU7X97Ue2w4zvMaybOnOo0/jOEjt6yBd+WToJzyUJQcg+Rwf2l0lONON4YpIVOtbvoBmQ3gEpYzze7RL+2RD9muQAnzFRLJoVTV8pcmngFwkqlhdKdwoIT4Tf7Eu1zEKhZjjrSFtgG//v0gZ45R7WkfP0NkogtgsSs1oFdZ5kEfDQjsQ3pMK2TR27phdIduBuhLRrWVK+LVQc4DCtkrOq3ddsAyhYr/8A== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=fail (sender ip is 84.19.233.75) smtp.rcpttodomain=cirrus.com smtp.mailfrom=opensource.cirrus.com; dmarc=fail (p=reject sp=reject pct=100) action=oreject header.from=opensource.cirrus.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus4.onmicrosoft.com; s=selector2-cirrus4-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=W/2VS7P03zRrZVR2i2nKw5NrfvIPu/CruEGB6xUCfbE=; b=ym4Z/yg2sFjM4Lb3pt+s6Ik0SBb5stVG9iDwBNd6rf1by3RctNzA4R0fI6kUw3iF1Hs5jrLUJvqedmzkgcWoPQ8iTdOHy2tmKS8qy2lFdIJOKYwk41QMSYNgdnGaNdRk6oVBbap+afhlEUDLd6hdjRvrSfwTl4Zb6MUy5BnSe4g= Received: from BYAPR21CA0004.namprd21.prod.outlook.com (2603:10b6:a03:114::14) by PH7PR19MB5751.namprd19.prod.outlook.com (2603:10b6:510:1d2::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9203.10; Tue, 21 Oct 2025 10:50:25 +0000 Received: from SJ1PEPF00002320.namprd03.prod.outlook.com (2603:10b6:a03:114:cafe::37) by BYAPR21CA0004.outlook.office365.com (2603:10b6:a03:114::14) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9275.4 via Frontend Transport; Tue, 21 Oct 2025 10:50:24 +0000 X-MS-Exchange-Authentication-Results: spf=fail (sender IP is 84.19.233.75) smtp.mailfrom=opensource.cirrus.com; dkim=none (message not signed) header.d=none;dmarc=fail action=oreject header.from=opensource.cirrus.com; Received-SPF: Fail (protection.outlook.com: domain of opensource.cirrus.com does not designate 84.19.233.75 as permitted sender) receiver=protection.outlook.com; client-ip=84.19.233.75; helo=edirelay1.ad.cirrus.com; Received: from edirelay1.ad.cirrus.com (84.19.233.75) by SJ1PEPF00002320.mail.protection.outlook.com (10.167.242.86) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9253.7 via Frontend Transport; Tue, 21 Oct 2025 10:50:24 +0000 Received: from ediswmail9.ad.cirrus.com (ediswmail9.ad.cirrus.com [198.61.86.93]) by edirelay1.ad.cirrus.com (Postfix) with ESMTPS id ADFFF406553; Tue, 21 Oct 2025 10:50:22 +0000 (UTC) Received: from ediswws06.ad.cirrus.com (ediswws06.ad.cirrus.com [198.90.208.24]) by ediswmail9.ad.cirrus.com (Postfix) with ESMTPSA id 70699822542; Tue, 21 Oct 2025 10:50:22 +0000 (UTC) From: Richard Fitzgerald To: broonie@kernel.org, tiwai@suse.com Cc: linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org, patches@opensource.cirrus.com Subject: [PATCH v2 03/11] ASoC: cs35l56: Add common code for factory calibration Date: Tue, 21 Oct 2025 11:50:14 +0100 Message-ID: <20251021105022.1013685-4-rf@opensource.cirrus.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251021105022.1013685-1-rf@opensource.cirrus.com> References: <20251021105022.1013685-1-rf@opensource.cirrus.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ1PEPF00002320:EE_|PH7PR19MB5751:EE_ X-MS-Office365-Filtering-Correlation-Id: 57e29a28-97a3-48a9-9a51-08de108fa397 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|82310400026|36860700013|61400799027; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?izatq5Krsa+QDTZHFltbvfRgSANY0KV3yfb5M1OuaPDyuCqELpbXYsXLSefC?= =?us-ascii?Q?YwFsIP02TGPQnPe09JbqubpgKdTjWAyzbQMnevlTu11+ZjT9SrxsCHmkb5re?= =?us-ascii?Q?samZuqGV1cSFt2TNAEcic5f2AMWa4jHf7WdyLoU2N525dXXL9hmY1qSuvsau?= =?us-ascii?Q?MRpTsKr8HvWP2zHX4Cr35eBzoo1E4iD+evKkbGQqe+s99yHNV3h/hOwP9Lx1?= =?us-ascii?Q?qLt+haRPPPKKQAixSwTBmzWjGueWKo4gV3BKopmA6mmEHPdZkRh6MIhlKWnR?= =?us-ascii?Q?0UAr32qQcrJoNmbVdXNgJtAeBbu9/SJ2akMnAP1dVLNAGIAv2GocOjU6XNTT?= =?us-ascii?Q?dBq8Y2tYKnjxLGJO4fhURHRTYhvvD8+6nwqlPvpjKM1yi/rSU2Y4ovMS0NFr?= =?us-ascii?Q?lY7+Ij/zXFx5vnt7e/H0JbXxHZeIvsfPPLQWD8haBqlRFoq4dCu18bXmt0uK?= =?us-ascii?Q?Xg6k/flDcuZuIsqFfA4lgMmDvmrEaHbbXJ0YB6VuEaJSZdbQTd3W1t6D6OaE?= =?us-ascii?Q?/LeivtMaezrw2PU6P3EyYMDiGQQEJh1VdKuBQHoNPA4KC0AGLJ5V8cXoUqwI?= =?us-ascii?Q?ZUsbq6rDZweo2z9bzCm4383e5GspqoxR4u16nks1LBnFpe0HfG00FPa9w/41?= =?us-ascii?Q?AB/wEiLVMCk6CnXBSK3hSuZkjT5qUvmOSD/ZoWl8XxZpJUzwbRDyeKbptaj3?= =?us-ascii?Q?lRe+rb8yJDzOAPdLpgnWUR84pcOw6cMRImlY9mpP4AuENzsx/hLYQ7Py5X5x?= =?us-ascii?Q?sxj5Q4z5chrJlPM1LZp5jYFXB56kHp4DqrgpOl41gGKhFoqou10qLyJr6KXi?= =?us-ascii?Q?opTFVTqhCs2XFpIPbuNrSrGNAAiqzKHaK5UFDWke36lFOZt4WkOd9r8XoWfm?= =?us-ascii?Q?XG911QqroAlBlWbwYDHT8PMYASJzI3MPmIuxCgiQfek8p2uj3QZoBtvNdDck?= =?us-ascii?Q?ucs3gxAZ15K99y+wUEq4GUnOFSMUIid3vkua6f484g4kzQtlzKG76hZzhGlw?= =?us-ascii?Q?2899qUwckFWzo/7vgeSyjedTJc4xnssDeAkBH2/DGwmAl2Tj3vbkFml3NH0R?= =?us-ascii?Q?GIA0bkbIJBn4WORnvdV9CWH5IuiDTifB9vC8FiPofIt4o8mcEjQnWtqCnWOZ?= =?us-ascii?Q?mj0eq2U9ogoQ52KjKZwpZHRjO53p6U014G29Mm6/9o8JsmhwgOP22O5VFBDn?= =?us-ascii?Q?NNiRmnRTPWU7HwlWkGpLK4rXArBDKl6EKwp5W0aPla8ttK2KJwzPuKKoSVZC?= =?us-ascii?Q?aYp0NRAleflExGlvj5f711c/8oOKvzhp+yarsi5DNZfjRpsfFnCiXy98gUlu?= =?us-ascii?Q?PdV55Fk1M6+PToeOf941jWZVSarMzQZRI9lEFXUPPMYqdYCr3Sg/9VYOkRVc?= =?us-ascii?Q?+jnof8edSzHjTbUIBcZNUV3n8BHXmIHk0d09pYlC/31HY2XFbKECC5lL7yup?= =?us-ascii?Q?sKh4F7oDggD2mBAaUzSqnMDyrMv4FzkkJHCOsbJggXZjxFBhxRjn092f6YIc?= =?us-ascii?Q?ti/9Zz9X3CYfkuFUkUDBunxcYPUCg85zFWzUkvItbVJz0tssl2R1pRzw5vGA?= =?us-ascii?Q?bKWQFZLl/jRddfNXSAk=3D?= X-Forefront-Antispam-Report: CIP:84.19.233.75;CTRY:GB;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:edirelay1.ad.cirrus.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(376014)(82310400026)(36860700013)(61400799027);DIR:OUT;SFP:1102; X-OriginatorOrg: opensource.cirrus.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Oct 2025 10:50:24.0828 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 57e29a28-97a3-48a9-9a51-08de108fa397 X-MS-Exchange-CrossTenant-Id: bec09025-e5bc-40d1-a355-8e955c307de8 X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=bec09025-e5bc-40d1-a355-8e955c307de8;Ip=[84.19.233.75];Helo=[edirelay1.ad.cirrus.com] X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: TreatMessagesAsInternal-SJ1PEPF00002320.namprd03.prod.outlook.com X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH7PR19MB5751 X-Proofpoint-ORIG-GUID: snNYJtQ0DAG7Rz_8apg-ns7xiVJJmuyB X-Proofpoint-GUID: snNYJtQ0DAG7Rz_8apg-ns7xiVJJmuyB X-Authority-Analysis: v=2.4 cv=bdNmkePB c=1 sm=1 tr=0 ts=68f76577 cx=c_pps a=i3X4t2Xqt3CcVAOequVlKw==:117 a=h1hSm8JtM9GN1ddwPAif2w==:17 a=6eWqkTHjU83fiwn7nKZWdM+Sl24=:19 a=z/mQ4Ysz8XfWz/Q5cLBRGdckG28=:19 a=x6icFKpwvdMA:10 a=s63m1ICgrNkA:10 a=RWc_ulEos4gA:10 a=VkNPw1HP01LnGYTKEx00:22 a=w1d2syhTAAAA:8 a=1V4PQ12dt87U5XisZtsA:9 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMDIxMDA4NSBTYWx0ZWRfX7Kwb235mEFSN KRD/dT/31rDml0+f1LYIhVL7H596T9P1lCsb4ytckWw6VFP4UtQwcZ+39iqD9mYy8ArmJ870gIX u8861ao4Sw+5or4F9lt8tBFeulvu19dogZP0Glcs0XtoLhsjycrrXgWBW9MQD9KAbwivDWFNcf5 r5WAIJqwGt87W8lZ4cvd6BtOH/65KPKruIRH8s1aNg+dqqBo93dqlTqSN2KehvC45f/kVg88RWF E6kzD04LONm30HY2voRKeSTM62bSEQlCJvqY4GbICY5iwN4Sw+lhdruVWGTWKVkkjeK13urLtM9 4AZ90FAfxXClf8FuIVucDmDNJzAXRDGSPTmm+MxZjvyxmEHRhRgvfZoB+W18VGhfVKbrGg6VyKo xThzAaY6/NVcdHsNB3iniC4j0HVAew== X-Proofpoint-Spam-Reason: safe Content-Type: text/plain; charset="utf-8" Add core code to support factory calibration. This can be used by both the ASoC and HDA drivers. This code consists of implementations of debugfs handlers for three debugfs files used to start factory calibration and read the results. This is not a full implementation of debugfs files. There are some requirements to synchronize with the rest of the amp driver, and the way this is done is significantly different between ASoC and HDA. Therefore cs35l56-shared.c provides the main part of the file handlers, but the files themselves are defined in the ASoC and HDA drivers with suitable handling before calling into this shared code. The cal_data file allows the calibration to be read and also for a previous calibration to be written (for systems where the storage is not something directly accessible to drivers, such as on filesystems). Code outside the kernel should treat the content of cal_data as an opaque blob, so the struct definition is not exported as a user API. Signed-off-by: Richard Fitzgerald Reviewed-by: Takashi Iwai --- Changes in V2: - File callbacks rewritten to be debugfs callbacks instead of sysfs callbacks. - Added a function to create the debugfs files. include/sound/cs35l56.h | 33 ++++ sound/soc/codecs/Kconfig | 3 + sound/soc/codecs/cs35l56-shared.c | 300 +++++++++++++++++++++++++++++- 3 files changed, 331 insertions(+), 5 deletions(-) diff --git a/include/sound/cs35l56.h b/include/sound/cs35l56.h index ec9b1072d6be..349b896ee737 100644 --- a/include/sound/cs35l56.h +++ b/include/sound/cs35l56.h @@ -9,6 +9,7 @@ #ifndef __CS35L56_H #define __CS35L56_H =20 +#include #include #include #include @@ -62,6 +63,8 @@ #define CS35L56_IRQ1_MASK_8 0x000E0AC #define CS35L56_IRQ1_MASK_18 0x000E0D4 #define CS35L56_IRQ1_MASK_20 0x000E0DC +#define CS35L56_MIXER_NGATE_CH1_CFG 0x0010004 +#define CS35L56_MIXER_NGATE_CH2_CFG 0x0010008 #define CS35L56_DSP_MBOX_1_RAW 0x0011000 #define CS35L56_DSP_VIRTUAL1_MBOX_1 0x0011020 #define CS35L56_DSP_VIRTUAL1_MBOX_2 0x0011024 @@ -177,6 +180,9 @@ /* IRQ1_EINT_8 */ #define CS35L56_TEMP_ERR_EINT1_MASK 0x80000000 =20 +/* MIXER_NGATE_CHn_CFG */ +#define CS35L56_AUX_NGATE_CHn_EN 0x00000001 + /* Mixer input sources */ #define CS35L56_INPUT_SRC_NONE 0x00 #define CS35L56_INPUT_SRC_ASP1RX1 0x08 @@ -243,6 +249,7 @@ #define CS35L56_MBOX_CMD_AUDIO_PLAY 0x0B000001 #define CS35L56_MBOX_CMD_AUDIO_PAUSE 0x0B000002 #define CS35L56_MBOX_CMD_AUDIO_REINIT 0x0B000003 +#define CS35L56_MBOX_CMD_AUDIO_CALIBRATION 0x0B000006 #define CS35L56_MBOX_CMD_HIBERNATE_NOW 0x02000001 #define CS35L56_MBOX_CMD_WAKEUP 0x02000002 #define CS35L56_MBOX_CMD_PREVENT_AUTO_HIBERNATE 0x02000003 @@ -264,6 +271,9 @@ #define CS35L56_RESET_PULSE_MIN_US 1100 #define CS35L56_WAKE_HOLD_TIME_US 1000 =20 +#define CS35L56_CALIBRATION_POLL_US (100 * USEC_PER_MSEC) +#define CS35L56_CALIBRATION_TIMEOUT_US (5 * USEC_PER_SEC) + #define CS35L56_SDW1_PLAYBACK_PORT 1 #define CS35L56_SDW1_CAPTURE_PORT 3 =20 @@ -291,9 +301,16 @@ struct cs35l56_fw_reg { unsigned int posture_number; }; =20 +struct cs35l56_cal_debugfs_fops { + const struct debugfs_short_fops calibrate; + const struct debugfs_short_fops cal_temperature; + const struct debugfs_short_fops cal_data; +}; + struct cs35l56_base { struct device *dev; struct regmap *regmap; + struct cs_dsp *dsp; int irq; struct mutex irq_lock; u8 type; @@ -309,6 +326,7 @@ struct cs35l56_base { struct cs35l56_spi_payload *spi_payload_buf; const struct cs35l56_fw_reg *fw_reg; const struct cirrus_amp_cal_controls *calibration_controls; + struct dentry *debugfs; u64 silicon_uid; }; =20 @@ -359,6 +377,21 @@ int cs35l56_runtime_suspend_common(struct cs35l56_base= *cs35l56_base); int cs35l56_runtime_resume_common(struct cs35l56_base *cs35l56_base, bool = is_soundwire); void cs35l56_init_cs_dsp(struct cs35l56_base *cs35l56_base, struct cs_dsp = *cs_dsp); int cs35l56_get_calibration(struct cs35l56_base *cs35l56_base); +ssize_t cs35l56_calibrate_debugfs_write(struct cs35l56_base *cs35l56_base, + const char __user *from, size_t count, + loff_t *ppos); +ssize_t cs35l56_cal_ambient_debugfs_write(struct cs35l56_base *cs35l56_bas= e, + const char __user *from, size_t count, + loff_t *ppos); +ssize_t cs35l56_cal_data_debugfs_read(struct cs35l56_base *cs35l56_base, + char __user *to, size_t count, + loff_t *ppos); +ssize_t cs35l56_cal_data_debugfs_write(struct cs35l56_base *cs35l56_base, + const char __user *from, size_t count, + loff_t *ppos); +void cs35l56_create_cal_debugfs(struct cs35l56_base *cs35l56_base, + const struct cs35l56_cal_debugfs_fops *fops); +void cs35l56_remove_cal_debugfs(struct cs35l56_base *cs35l56_base); int cs35l56_read_prot_status(struct cs35l56_base *cs35l56_base, bool *fw_missing, unsigned int *fw_version); void cs35l56_log_tuning(struct cs35l56_base *cs35l56_base, struct cs_dsp *= cs_dsp); diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 160c07699a8b..6bb24325c2d0 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -896,6 +896,9 @@ config SND_SOC_CS35L56_SDW help Enable support for Cirrus Logic CS35L56 boosted amplifier with SoundWir= e control =20 +config SND_SOC_CS35L56_CAL_DEBUGFS_COMMON + bool + config SND_SOC_CS40L50 tristate "Cirrus Logic CS40L50 CODEC" depends on MFD_CS40L50_CORE diff --git a/sound/soc/codecs/cs35l56-shared.c b/sound/soc/codecs/cs35l56-s= hared.c index 1ecfc38d8eb4..eeb830e3f743 100644 --- a/sound/soc/codecs/cs35l56-shared.c +++ b/sound/soc/codecs/cs35l56-shared.c @@ -6,11 +6,18 @@ // Cirrus Logic International Semiconductor Ltd. =20 #include +#include +#include #include +#include #include +#include #include #include #include +#include +#include +#include #include #include =20 @@ -206,6 +213,8 @@ static bool cs35l56_readable_reg(struct device *dev, un= signed int reg) case CS35L56_IRQ1_MASK_8: case CS35L56_IRQ1_MASK_18: case CS35L56_IRQ1_MASK_20: + case CS35L56_MIXER_NGATE_CH1_CFG: + case CS35L56_MIXER_NGATE_CH2_CFG: case CS35L56_DSP_VIRTUAL1_MBOX_1: case CS35L56_DSP_VIRTUAL1_MBOX_2: case CS35L56_DSP_VIRTUAL1_MBOX_3: @@ -263,6 +272,8 @@ static bool cs35l56_common_volatile_reg(unsigned int re= g) case CS35L56_IRQ1_EINT_1 ... CS35L56_IRQ1_EINT_8: case CS35L56_IRQ1_EINT_18: case CS35L56_IRQ1_EINT_20: + case CS35L56_MIXER_NGATE_CH1_CFG: + case CS35L56_MIXER_NGATE_CH2_CFG: case CS35L56_DSP_VIRTUAL1_MBOX_1: case CS35L56_DSP_VIRTUAL1_MBOX_2: case CS35L56_DSP_VIRTUAL1_MBOX_3: @@ -724,15 +735,11 @@ static void cs35l56_issue_wake_event(struct cs35l56_b= ase *cs35l56_base) cs35l56_wait_control_port_ready(); } =20 -int cs35l56_runtime_suspend_common(struct cs35l56_base *cs35l56_base) +static int cs35l56_wait_for_ps3(struct cs35l56_base *cs35l56_base) { unsigned int val; int ret; =20 - if (!cs35l56_base->init_done) - return 0; - - /* Firmware must have entered a power-save state */ ret =3D regmap_read_poll_timeout(cs35l56_base->regmap, cs35l56_base->fw_reg->transducer_actual_ps, val, (val >=3D CS35L56_PS3), @@ -741,6 +748,17 @@ int cs35l56_runtime_suspend_common(struct cs35l56_base= *cs35l56_base) if (ret) dev_warn(cs35l56_base->dev, "PS3 wait failed: %d\n", ret); =20 + return ret; +} + +int cs35l56_runtime_suspend_common(struct cs35l56_base *cs35l56_base) +{ + if (!cs35l56_base->init_done) + return 0; + + /* Firmware must have entered a power-save state */ + cs35l56_wait_for_ps3(cs35l56_base); + /* Clear BOOT_DONE so it can be used to detect a reboot */ regmap_write(cs35l56_base->regmap, CS35L56_IRQ1_EINT_4, CS35L56_OTP_BOOT_= DONE_MASK); =20 @@ -839,6 +857,8 @@ void cs35l56_init_cs_dsp(struct cs35l56_base *cs35l56_b= ase, struct cs_dsp *cs_ds cs_dsp->mem =3D cs35l56_dsp1_regions; cs_dsp->num_mems =3D ARRAY_SIZE(cs35l56_dsp1_regions); cs_dsp->no_core_startstop =3D true; + + cs35l56_base->dsp =3D cs_dsp; } EXPORT_SYMBOL_NS_GPL(cs35l56_init_cs_dsp, "SND_SOC_CS35L56_SHARED"); =20 @@ -942,6 +962,276 @@ int cs35l56_get_calibration(struct cs35l56_base *cs35= l56_base) } EXPORT_SYMBOL_NS_GPL(cs35l56_get_calibration, "SND_SOC_CS35L56_SHARED"); =20 +static int cs35l56_stash_calibration(struct cs35l56_base *cs35l56_base, + const struct cirrus_amp_cal_data *data) +{ + + /* Ignore if it is empty */ + if (!data->calTime[0] && !data->calTime[1]) + return -ENODATA; + + if (cs_amp_cal_target_u64(data) !=3D cs35l56_base->silicon_uid) { + dev_err(cs35l56_base->dev, "cal_data not for this silicon ID\n"); + return -EINVAL; + } + + cs35l56_base->cal_data =3D *data; + cs35l56_base->cal_data_valid =3D true; + + return 0; +} + +static int cs35l56_perform_calibration(struct cs35l56_base *cs35l56_base) +{ + const struct cirrus_amp_cal_controls *calibration_controls =3D + cs35l56_base->calibration_controls; + struct cs_dsp *dsp =3D cs35l56_base->dsp; + struct cirrus_amp_cal_data cal_data; + struct cs_dsp_coeff_ctl *ctl; + bool ngate_ch1_was_enabled =3D false; + bool ngate_ch2_was_enabled =3D false; + int cali_norm_en_alg_id, cali_norm_en_mem; + int ret; + __be32 val; + + if (cs35l56_base->silicon_uid =3D=3D 0) { + dev_err(cs35l56_base->dev, "Cannot calibrate: no silicon UID\n"); + return -ENXIO; + } + + switch (cs35l56_base->type) { + case 0x54: + case 0x56: + case 0x57: + if (cs35l56_base->rev < 0xb2) { + cali_norm_en_alg_id =3D 0x9f22f; + cali_norm_en_mem =3D WMFW_ADSP2_YM; + } else { + cali_norm_en_alg_id =3D 0x9f210; + cali_norm_en_mem =3D WMFW_ADSP2_XM; + } + break; + default: + cali_norm_en_alg_id =3D 0xbf210; + cali_norm_en_mem =3D WMFW_ADSP2_XM; + break; + } + + ret =3D pm_runtime_resume_and_get(cs35l56_base->dev); + if (ret) + return ret; + + ret =3D cs35l56_wait_for_ps3(cs35l56_base); + if (ret) + goto err_pm_put; + + regmap_update_bits_check(cs35l56_base->regmap, CS35L56_MIXER_NGATE_CH1_CF= G, + CS35L56_AUX_NGATE_CHn_EN, 0, &ngate_ch1_was_enabled); + regmap_update_bits_check(cs35l56_base->regmap, CS35L56_MIXER_NGATE_CH2_CF= G, + CS35L56_AUX_NGATE_CHn_EN, 0, &ngate_ch2_was_enabled); + + scoped_guard(mutex, &dsp->pwr_lock) { + ctl =3D cs_dsp_get_ctl(dsp, + calibration_controls->status, + calibration_controls->mem_region, + calibration_controls->alg_id); + if (!ctl) { + dev_err(cs35l56_base->dev, "Could not get %s control\n", + calibration_controls->status); + ret =3D -ENXIO; + goto err; + } + + val =3D cpu_to_be32(0); + ret =3D cs_dsp_coeff_write_ctrl(cs_dsp_get_ctl(dsp, + "CALI_NORM_EN", + cali_norm_en_mem, + cali_norm_en_alg_id), + 0, &val, sizeof(val)); + if (ret < 0) { + dev_err(cs35l56_base->dev, "Could not write %s: %d\n", "CALI_NORM_EN", = ret); + goto err; + } + + ret =3D cs35l56_mbox_send(cs35l56_base, CS35L56_MBOX_CMD_AUDIO_CALIBRATI= ON); + if (ret) + goto err; + + if (read_poll_timeout(cs_dsp_coeff_read_ctrl, ret, + (val =3D=3D cpu_to_be32(1)), + CS35L56_CALIBRATION_POLL_US, + CS35L56_CALIBRATION_TIMEOUT_US, + true, + ctl, 0, &val, sizeof(val))) { + dev_err(cs35l56_base->dev, "Calibration timed out (CAL_STATUS: %u)\n", + be32_to_cpu(val)); + ret =3D -ETIMEDOUT; + goto err; + } + } + + cs35l56_base->cal_data_valid =3D false; + memset(&cal_data, 0, sizeof(cal_data)); + ret =3D cs_amp_read_cal_coeffs(dsp, calibration_controls, &cal_data); + if (ret) + goto err; + + dev_info(cs35l56_base->dev, "Cal status:%d calR:%d ambient:%d\n", + cal_data.calStatus, cal_data.calR, cal_data.calAmbient); + + cal_data.calTarget[0] =3D (u32)cs35l56_base->silicon_uid; + cal_data.calTarget[1] =3D (u32)(cs35l56_base->silicon_uid >> 32); + cs35l56_base->cal_data =3D cal_data; + cs35l56_base->cal_data_valid =3D true; + + ret =3D 0; + +err: + if (ngate_ch1_was_enabled) { + regmap_set_bits(cs35l56_base->regmap, CS35L56_MIXER_NGATE_CH1_CFG, + CS35L56_AUX_NGATE_CHn_EN); + } + if (ngate_ch2_was_enabled) { + regmap_set_bits(cs35l56_base->regmap, CS35L56_MIXER_NGATE_CH2_CFG, + CS35L56_AUX_NGATE_CHn_EN); + } +err_pm_put: + pm_runtime_put(cs35l56_base->dev); + + return ret; +} + +ssize_t cs35l56_calibrate_debugfs_write(struct cs35l56_base *cs35l56_base, + const char __user *from, size_t count, + loff_t *ppos) +{ + static const char * const options[] =3D { "factory" }; + char buf[8] =3D { 0 }; + int ret; + + if (!IS_ENABLED(CONFIG_SND_SOC_CS35L56_CAL_DEBUGFS_COMMON)) + return -ENXIO; + + if (*ppos) + return -EINVAL; + + ret =3D simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, from, count); + if (ret < 0) + return ret; + + switch (sysfs_match_string(options, buf)) { + case 0: + ret =3D cs35l56_perform_calibration(cs35l56_base); + if (ret < 0) + return ret; + break; + default: + return -ENXIO; + } + + return count; +} +EXPORT_SYMBOL_NS_GPL(cs35l56_calibrate_debugfs_write, "SND_SOC_CS35L56_SHA= RED"); + +ssize_t cs35l56_cal_ambient_debugfs_write(struct cs35l56_base *cs35l56_bas= e, + const char __user *from, size_t count, + loff_t *ppos) +{ + unsigned long val; + int ret; + + if (!IS_ENABLED(CONFIG_SND_SOC_CS35L56_CAL_DEBUGFS_COMMON)) + return -ENXIO; + + if (*ppos) + return -EINVAL; + + ret =3D pm_runtime_resume_and_get(cs35l56_base->dev); + if (ret) + return ret; + + ret =3D kstrtoul_from_user(from, count, 10, &val); + if (ret < 0) + goto out; + + ret =3D cs_amp_write_ambient_temp(cs35l56_base->dsp, cs35l56_base->calibr= ation_controls, val); +out: + pm_runtime_put(cs35l56_base->dev); + + if (ret < 0) + return ret; + + return count; +} +EXPORT_SYMBOL_NS_GPL(cs35l56_cal_ambient_debugfs_write, "SND_SOC_CS35L56_S= HARED"); + +ssize_t cs35l56_cal_data_debugfs_read(struct cs35l56_base *cs35l56_base, + char __user *to, size_t count, + loff_t *ppos) +{ + if (!IS_ENABLED(CONFIG_SND_SOC_CS35L56_CAL_DEBUGFS_COMMON)) + return -ENXIO; + + if (!cs35l56_base->cal_data_valid) + return 0; + + return simple_read_from_buffer(to, count, ppos, &cs35l56_base->cal_data, + sizeof(cs35l56_base->cal_data)); +} +EXPORT_SYMBOL_NS_GPL(cs35l56_cal_data_debugfs_read, "SND_SOC_CS35L56_SHARE= D"); + +ssize_t cs35l56_cal_data_debugfs_write(struct cs35l56_base *cs35l56_base, + const char __user *from, size_t count, + loff_t *ppos) +{ + struct cirrus_amp_cal_data cal_data; + int ret; + + if (!IS_ENABLED(CONFIG_SND_SOC_CS35L56_CAL_DEBUGFS_COMMON)) + return -ENXIO; + + /* Only allow a full blob to be written */ + if (*ppos || (count !=3D sizeof(cal_data))) + return -EMSGSIZE; + + ret =3D simple_write_to_buffer(&cal_data, sizeof(cal_data), ppos, from, c= ount); + if (ret) + return ret; + + ret =3D cs35l56_stash_calibration(cs35l56_base, &cal_data); + if (ret) + return ret; + + return count; +} +EXPORT_SYMBOL_NS_GPL(cs35l56_cal_data_debugfs_write, "SND_SOC_CS35L56_SHAR= ED"); + +void cs35l56_create_cal_debugfs(struct cs35l56_base *cs35l56_base, + const struct cs35l56_cal_debugfs_fops *fops) +{ + if (!IS_ENABLED(CONFIG_SND_SOC_CS35L56_CAL_DEBUGFS_COMMON)) + return; + + cs35l56_base->debugfs =3D cs_amp_create_debugfs(cs35l56_base->dev); + + debugfs_create_file("calibrate", + 0200, cs35l56_base->debugfs, cs35l56_base, + &fops->calibrate); + debugfs_create_file("cal_temperature", + 0200, cs35l56_base->debugfs, cs35l56_base, + &fops->cal_temperature); + debugfs_create_file("cal_data", + 0644, cs35l56_base->debugfs, cs35l56_base, + &fops->cal_data); +} +EXPORT_SYMBOL_NS_GPL(cs35l56_create_cal_debugfs, "SND_SOC_CS35L56_SHARED"); + +void cs35l56_remove_cal_debugfs(struct cs35l56_base *cs35l56_base) +{ + debugfs_remove_recursive(cs35l56_base->debugfs); +} +EXPORT_SYMBOL_NS_GPL(cs35l56_remove_cal_debugfs, "SND_SOC_CS35L56_SHARED"); + int cs35l56_read_prot_status(struct cs35l56_base *cs35l56_base, bool *fw_missing, unsigned int *fw_version) { --=20 2.47.3 From nobody Sun Feb 8 07:52:31 2026 Received: from mx0b-001ae601.pphosted.com (mx0b-001ae601.pphosted.com [67.231.152.168]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C31AE32B996; Tue, 21 Oct 2025 10:50:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=67.231.152.168 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761043837; cv=fail; b=WQ9RmTZfw1Yh7yVYXfwt6Ri7rU3AbmEA4O0IxSBRAGMYs2VwM/NHuhpeWHWYt7YwLs2y8sPb7Zkkd3PsrkJkZGflLtLqhqAT4TfwSHKg+iwF4KuAiISMDM+Yj9Q/8RTub93xzPjJ5A+VWA+h6FjLdVSYZcmK5xbaGORfjZ4RQ40= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761043837; c=relaxed/simple; bh=37q0JKpe2Mp0YgPPauiFM104kzzC7XRXuOaUpd0wYF8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=PRij3gVXEd7szyagaVsDFzIzklf2zR+8iNJRG0Mwr/0So8RGzlBnFigPSdef1qQMRYtF6piSchkmKIIIa+5V0+6tfM86LgtJJOhOACIUrQFxARxD0z4IKnniGRrEDfHYsZTsANOAO1zhMcL2r2nyIu83EUO2WG9yBVEemexFc+U= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=opensource.cirrus.com; spf=pass smtp.mailfrom=opensource.cirrus.com; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b=JdibM4eZ; dkim=pass (1024-bit key) header.d=cirrus4.onmicrosoft.com header.i=@cirrus4.onmicrosoft.com header.b=D7ZKzrs2; arc=fail smtp.client-ip=67.231.152.168 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=opensource.cirrus.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=opensource.cirrus.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="JdibM4eZ"; dkim=pass (1024-bit key) header.d=cirrus4.onmicrosoft.com header.i=@cirrus4.onmicrosoft.com header.b="D7ZKzrs2" Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 59KNfWTY1890847; Tue, 21 Oct 2025 05:50:31 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s= PODMain02222019; bh=5hR3KxRU+QBSaVTOizQdCCRhJEsaXyEtCKttqx10ozs=; b= JdibM4eZmlSknS5qFr4EmVQ3tgJU4XbgRTgTGkiFvhX/1hrrRfgzxUEjPb+DilCe YARNhAtaDaNiHeSl8rtqp3jbuGSnzLGhyXZl3z/OKRpBDdG8tZ92O/2wgXy2CEZv 6RvbsGQbfLUQEXAoPE55y3z/RpGMHBqshAjRfp8FjT7/uPMcqvsMa0o/x6iDaxkP KtF17gCuG1n75t+VMSD8/hXLzdhTYumYVzz4eoaPIXA/yE3Cs2idyUjfIEDoiN0K 71SFX+wt6t0wKRTc7Cpp52vfKk70aKcvDKt+Sz3Jv2+lB9ZySh62bEWLVdF47FeX dnqU0KXTe/NsURA+VlvgPQ== Received: from ch4pr04cu002.outbound.protection.outlook.com (mail-northcentralusazon11023087.outbound.protection.outlook.com [40.107.201.87]) by mx0b-001ae601.pphosted.com (PPS) with ESMTPS id 49v7aj3eg2-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Tue, 21 Oct 2025 05:50:31 -0500 (CDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=PVwI2ZftsBdVhfvWMrYPZqspDDC99/IlATFG6gtIKcUKia2IB8FmnC5IvvQME4Yb+oQLgTz3xKKSrBUnnLiWDRmtvkQtriDt6vFwSechl1mMK8NX5h3pj8WYtm82rZp9sZvzRAc+hPn2UeRQxGoxxtbEGLeMFEXDTfpSnNrFmyy8nqwbjaA/tEigVB9EZ415o1JNOH0zCXH0LncMv01AJbLSwMjLEHFhDPbAg2JlaeodleQfsV5oDsMMLi6tAhDooIOkLQl69PUhjsCh3B8JD87dda+4WSYWQ0INYisvLTXcY2E2eQbbltihoC0JTqJY2eaNiThDzV0SXvdU4LAxxg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=5hR3KxRU+QBSaVTOizQdCCRhJEsaXyEtCKttqx10ozs=; b=RaNp2u0L3cLmr4gBk+RohOJqtWqH6xGkwE8BmC3KUeBn3Qsx67DyPJR3VsUO78WxLWOpKEYXV7ALhD2aCpmZVtz6mxwgtVcSAjeB48Ex5Z+Yv/VMyaXYvKtDTm/8Uz6Xn3d7WQp+G9U5lz9HjRncdpM6qMljUJLAJNME9W0hJ5fLGpWaGkTPGbDyWu9Rb6WkFvTTD/AZsErZB/Zi+EOR/HUrfmfTaGOMHLqmKyVZJDAWhAbcBdmMsb6ZGJWec80jHk/89v8FZRmpR0XcuKv36ku4OlewCEwnD5tXiDfM8QlN8/EIPMj97U3zb8qlZ58fd48GZJemTfXYsDVZlrQ+HA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=fail (sender ip is 84.19.233.75) smtp.rcpttodomain=cirrus.com smtp.mailfrom=opensource.cirrus.com; dmarc=fail (p=reject sp=reject pct=100) action=oreject header.from=opensource.cirrus.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus4.onmicrosoft.com; s=selector2-cirrus4-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=5hR3KxRU+QBSaVTOizQdCCRhJEsaXyEtCKttqx10ozs=; b=D7ZKzrs2nleo1HcGJJyfMXQ6KmZGwvjIDglJfOx07j4ojlyCHy5NnL3kfZov00xLxkto5YiAS8jHVIz5xu6VJWeYJucvm637GU+l8bbK8jVGY14w/TO5T2C45Tha2ZQA0Hc2XDsz3084KnRuGsaqO4aFBUQEcWDzixf7IUmC71g= Received: from BYAPR11CA0092.namprd11.prod.outlook.com (2603:10b6:a03:f4::33) by BN5PR19MB8966.namprd19.prod.outlook.com (2603:10b6:408:2ac::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9228.17; Tue, 21 Oct 2025 10:50:26 +0000 Received: from SJ1PEPF00002326.namprd03.prod.outlook.com (2603:10b6:a03:f4:cafe::a) by BYAPR11CA0092.outlook.office365.com (2603:10b6:a03:f4::33) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9228.17 via Frontend Transport; Tue, 21 Oct 2025 10:50:25 +0000 X-MS-Exchange-Authentication-Results: spf=fail (sender IP is 84.19.233.75) smtp.mailfrom=opensource.cirrus.com; dkim=none (message not signed) header.d=none;dmarc=fail action=oreject header.from=opensource.cirrus.com; Received-SPF: Fail (protection.outlook.com: domain of opensource.cirrus.com does not designate 84.19.233.75 as permitted sender) receiver=protection.outlook.com; client-ip=84.19.233.75; helo=edirelay1.ad.cirrus.com; Received: from edirelay1.ad.cirrus.com (84.19.233.75) by SJ1PEPF00002326.mail.protection.outlook.com (10.167.242.89) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9253.7 via Frontend Transport; Tue, 21 Oct 2025 10:50:24 +0000 Received: from ediswmail9.ad.cirrus.com (ediswmail9.ad.cirrus.com [198.61.86.93]) by edirelay1.ad.cirrus.com (Postfix) with ESMTPS id AFF0F406555; Tue, 21 Oct 2025 10:50:22 +0000 (UTC) Received: from ediswws06.ad.cirrus.com (ediswws06.ad.cirrus.com [198.90.208.24]) by ediswmail9.ad.cirrus.com (Postfix) with ESMTPSA id 7521E822543; Tue, 21 Oct 2025 10:50:22 +0000 (UTC) From: Richard Fitzgerald To: broonie@kernel.org, tiwai@suse.com Cc: linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org, patches@opensource.cirrus.com Subject: [PATCH v2 04/11] ASoC: cs35l56: Create debugfs files for factory calibration Date: Tue, 21 Oct 2025 11:50:15 +0100 Message-ID: <20251021105022.1013685-5-rf@opensource.cirrus.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251021105022.1013685-1-rf@opensource.cirrus.com> References: <20251021105022.1013685-1-rf@opensource.cirrus.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ1PEPF00002326:EE_|BN5PR19MB8966:EE_ X-MS-Office365-Filtering-Correlation-Id: 82a2e39f-1490-4274-3da9-08de108fa3e4 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|61400799027|36860700013|376014|82310400026; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?f7ofE7OCT2XsVABTnRjEcZYDUwxY85WO0LLHdEOH7f8MJL6kXjYXc9qyxrAq?= =?us-ascii?Q?ZGS95m/WoT6u3h/eYiOEsWh4sdx8v9Oz7V1F6HUWvBGg0mZO5/bUJdtwN2qO?= =?us-ascii?Q?wYDftLnew5vpjCruy8wOxQiazLkw+e4UaUL/XKhgbvGlYjBVVWNZImH1pNaC?= =?us-ascii?Q?tHxgsJhcIsjGraswn7vGhk1X+mjXFHZU5SnvVjaJsyA87UM8Cjq0gsAuY/wc?= =?us-ascii?Q?dfNwYZko4xgiZL6gZ31FsXCAB64nuWp3eAh5T3HX33wFDBAqpbPaKyJmIuQv?= =?us-ascii?Q?dMu39m41uFZkxjvyDhF+8uHVfHn7YgsTei2wv4lEhhLQRDvEuHd9eQfAXmOj?= =?us-ascii?Q?VbrC96t90THmiPSLFoL21HiwsTDeiTnLuV/h/eDZOTG3S4cLAlZ9gu+FJB92?= =?us-ascii?Q?4qO6jyJMdI4rxSL1RRzeEgVLxcXPH8zj5pAp/KWRTyw5s5cs6dsAxf7crAuR?= =?us-ascii?Q?2R8WQxjwG5zuNnVSr6k40zsVLyPlh1W0Mg9jLvT5ihM9fzeXXoKbvVJBDf03?= =?us-ascii?Q?Wj4szZUeyjiJa03HkseLpBfp2R3JfVH0h0YeUGDGTNdV2yvngWE3wXJjz714?= =?us-ascii?Q?RQpo5uSfdH6mFQZnk8YIhsctpr//2441YUa4YhbbN4LHHQYEvqjKYXbvd46f?= =?us-ascii?Q?j/xjPQUSF2fh0S5ECxTB50nNw47P0dvuUVnWrA+Rg8uHpYSnxmU2wZjgVGWd?= =?us-ascii?Q?WeA/cd1/N68Kc5KRF8y7yf6o2qnv8hsdayN/r2Kp7xafoICHvadbit2eVLrp?= =?us-ascii?Q?50uxGEvDi5MYqThHge/B8aGYdRo4zU80aURFFCrulwgVrTe+S1djRWSI0KxT?= =?us-ascii?Q?sop+W+SEVC7gqn6aSQqMkax4h0tSUbZ4pykxJDwU7LOXCstOhCLq4sPbTI2i?= =?us-ascii?Q?x25l66MES2yc1EVmb3jxVmmNAqHWnitg1ZxshOMcWvTeyo0o7Dx7OkPHZMvJ?= =?us-ascii?Q?DrGKo+b0tqBmoxpptQZEu/iY9fX98ZZTMLEOk5ppb9D2N+8Ey4JKdmaF1NH1?= =?us-ascii?Q?vgynWncJIeJkJqTJ7Wh9NfRKUmAk+FzLuS6POaufGtfx+eDX1pXgLt9Fuv/H?= =?us-ascii?Q?QjfamddR6F2vyQJ+jjVWR7R2hmZ85H6hAswyoBig4Q4/257t94PFScm72Zqm?= =?us-ascii?Q?/Trkgrw/9MVKkZKBI2MqeFDbBLNW2IfstSQuVoKdrPSK8c++rfDCJnx12Cc9?= =?us-ascii?Q?wZvxtR9TbqwWGKt9871v6TnPb5hetnlKhlnxfwHIDGGHwPq+vTEz6grYLNZq?= =?us-ascii?Q?TUHdTyk1QeIm73iy4iauQBNQ4ZWsaKvfWl0r/e5Eewj/vl+L8o0Kq50vGkxv?= =?us-ascii?Q?5Qg2i1WSq4jcmBHTVj/nLUIwH1oEUHz7NPiuPVwBPnP6cqIKid/S5PbttHcL?= =?us-ascii?Q?fABS0IbKtrhyTJZyMy6b3+cqwH+GibK2sbG0TXT5jKeSY2QPDfXYlz2L+uKR?= =?us-ascii?Q?l1RQN5cRCB400RFKHpTifjLVTISDJ2bWMWrAKNmkA9I/ha9Crs6SZvhkAU9l?= =?us-ascii?Q?EysrR2+SsBj/NlMuaj3VmxwXdiCIlBuzyp4OTSWHqU/ki8wmeMaKDQk2Nc7q?= =?us-ascii?Q?L9xp/tPhB7l4sTIPC0A=3D?= X-Forefront-Antispam-Report: CIP:84.19.233.75;CTRY:GB;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:edirelay1.ad.cirrus.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(61400799027)(36860700013)(376014)(82310400026);DIR:OUT;SFP:1102; X-OriginatorOrg: opensource.cirrus.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Oct 2025 10:50:24.5849 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 82a2e39f-1490-4274-3da9-08de108fa3e4 X-MS-Exchange-CrossTenant-Id: bec09025-e5bc-40d1-a355-8e955c307de8 X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=bec09025-e5bc-40d1-a355-8e955c307de8;Ip=[84.19.233.75];Helo=[edirelay1.ad.cirrus.com] X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: TreatMessagesAsInternal-SJ1PEPF00002326.namprd03.prod.outlook.com X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN5PR19MB8966 X-Proofpoint-ORIG-GUID: E7K8ts0c7D8umh3EAo4qIQIMNb3pMx_4 X-Proofpoint-GUID: E7K8ts0c7D8umh3EAo4qIQIMNb3pMx_4 X-Authority-Analysis: v=2.4 cv=bdNmkePB c=1 sm=1 tr=0 ts=68f76577 cx=c_pps a=poqohWOkhvWL7PloZTu5+Q==:117 a=h1hSm8JtM9GN1ddwPAif2w==:17 a=6eWqkTHjU83fiwn7nKZWdM+Sl24=:19 a=z/mQ4Ysz8XfWz/Q5cLBRGdckG28=:19 a=x6icFKpwvdMA:10 a=s63m1ICgrNkA:10 a=RWc_ulEos4gA:10 a=VkNPw1HP01LnGYTKEx00:22 a=w1d2syhTAAAA:8 a=FN_7tG6lu9g4JpDWAFIA:9 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMDIxMDA4NSBTYWx0ZWRfX0mf6LwxylrLF Lfc0h4wYk34cjKs1F/TD/5fCp2Bqc34xtgJvisa5GmT8sG7SH7OPXIb172IjCGH/i1adYK2rXtF pHWA8yCoP8Kygk8pCg8JQQvlkY4Jk52lmNn62eYbkGgW3a7xiTkQK7hUjVKgOP0IxoMbY5HW3Y0 TEAsj2mv77rNI4+CYjAR0wO1tSy4W0g8bwO8FaA9O386ilO+muLLc0owv2FGLyW7yczUHixcPRy OEwHOK2vZtvqRqiDm13UKgOH3XF127blUXlM7naIFDntvNNG57RXHpb9Wv+JUwflNKQjBltHXWm xwl7nin7Iu28gA/yf86fWGSvRPg2Y9sb2ZTTWhV1NlzDfsBAZbf1Ye02KuKXvQWpk+2B/kJxYlE knO9xEwlUGr1LoZqW1mVMB9HPG3s2A== X-Proofpoint-Spam-Reason: safe Content-Type: text/plain; charset="utf-8" Create debugfs files that can be used to perform factory calibration. During manufacture, the production line must perform a factory calibration of the amps. This patch adds this functionality via debugfs files. As this is only needed during manufacture, there is no need for this to be available in a normal system so a Kconfig item has been added to enable this. The new Kconfig option is inside a sub-menu because items do not group and indent if the parent is invisible or there are multiple parent dependencies. Anyway the sub-menu reduces the clutter. Signed-off-by: Richard Fitzgerald Reviewed-by: Takashi Iwai --- Changes in V2: - File callbacks rewritten to be debugfs callbacks instead of sysfs callbacks. - Replace the sysfs file definition and creation with debugfs creation. sound/soc/codecs/Kconfig | 15 ++++ sound/soc/codecs/cs35l56.c | 159 +++++++++++++++++++++++++++++++++++++ sound/soc/codecs/cs35l56.h | 6 ++ 3 files changed, 180 insertions(+) diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 6bb24325c2d0..1e649da53ed9 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -899,6 +899,21 @@ config SND_SOC_CS35L56_SDW config SND_SOC_CS35L56_CAL_DEBUGFS_COMMON bool =20 +menu "CS35L56 driver options" + depends on SND_SOC_CS35L56 + +config SND_SOC_CS35L56_CAL_DEBUGFS + bool "CS35L56 create debugfs for factory calibration" + default N + depends on DEBUG_FS + select SND_SOC_CS35L56_CAL_DEBUGFS_COMMON + help + Create debugfs entries used during factory-line manufacture + for factory calibration. + + If unsure select "N". +endmenu + config SND_SOC_CS40L50 tristate "Cirrus Logic CS40L50 CODEC" depends on MFD_CS40L50_CORE diff --git a/sound/soc/codecs/cs35l56.c b/sound/soc/codecs/cs35l56.c index 2c1edbd636ef..091a72325507 100644 --- a/sound/soc/codecs/cs35l56.c +++ b/sound/soc/codecs/cs35l56.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -250,6 +251,8 @@ static const struct snd_soc_dapm_widget cs35l56_dapm_wi= dgets[] =3D { SND_SOC_DAPM_SIGGEN("VDDBMON ADC"), SND_SOC_DAPM_SIGGEN("VBSTMON ADC"), SND_SOC_DAPM_SIGGEN("TEMPMON ADC"), + + SND_SOC_DAPM_INPUT("Calibrate"), }; =20 #define CS35L56_SRC_ROUTE(name) \ @@ -286,6 +289,7 @@ static const struct snd_soc_dapm_route cs35l56_audio_ma= p[] =3D { { "DSP1", NULL, "ASP1RX1" }, { "DSP1", NULL, "ASP1RX2" }, { "DSP1", NULL, "SDW1 Playback" }, + { "DSP1", NULL, "Calibrate" }, { "AMP", NULL, "DSP1" }, { "SPK", NULL, "AMP" }, =20 @@ -874,6 +878,152 @@ static void cs35l56_dsp_work(struct work_struct *work) pm_runtime_put_autosuspend(cs35l56->base.dev); } =20 +static struct snd_soc_dapm_context *cs35l56_power_up_for_cal(struct cs35l5= 6_private *cs35l56) +{ + struct snd_soc_dapm_context *dapm =3D snd_soc_component_get_dapm(cs35l56-= >component); + int ret; + + ret =3D snd_soc_component_enable_pin(cs35l56->component, "Calibrate"); + if (ret) + return ERR_PTR(ret); + + snd_soc_dapm_sync(dapm); + + return dapm; +} + +static void cs35l56_power_down_after_cal(struct cs35l56_private *cs35l56) +{ + struct snd_soc_dapm_context *dapm =3D snd_soc_component_get_dapm(cs35l56-= >component); + + snd_soc_component_disable_pin(cs35l56->component, "Calibrate"); + snd_soc_dapm_sync(dapm); +} + +static ssize_t cs35l56_debugfs_calibrate_write(struct file *file, + const char __user *from, + size_t count, loff_t *ppos) +{ + struct cs35l56_base *cs35l56_base =3D file->private_data; + struct cs35l56_private *cs35l56 =3D cs35l56_private_from_base(cs35l56_bas= e); + struct snd_soc_dapm_context *dapm; + ssize_t ret; + + dapm =3D cs35l56_power_up_for_cal(cs35l56); + if (IS_ERR(dapm)) + return PTR_ERR(dapm); + + snd_soc_dapm_mutex_lock(dapm); + ret =3D cs35l56_calibrate_debugfs_write(&cs35l56->base, from, count, ppos= ); + snd_soc_dapm_mutex_unlock(dapm); + + cs35l56_power_down_after_cal(cs35l56); + + return ret; +} + +static ssize_t cs35l56_debugfs_cal_temperature_write(struct file *file, + const char __user *from, + size_t count, loff_t *ppos) +{ + struct cs35l56_base *cs35l56_base =3D file->private_data; + struct cs35l56_private *cs35l56 =3D cs35l56_private_from_base(cs35l56_bas= e); + struct snd_soc_dapm_context *dapm; + ssize_t ret; + + dapm =3D cs35l56_power_up_for_cal(cs35l56); + if (IS_ERR(dapm)) + return PTR_ERR(dapm); + + ret =3D cs35l56_cal_ambient_debugfs_write(&cs35l56->base, from, count, pp= os); + cs35l56_power_down_after_cal(cs35l56); + + return ret; +} + +static ssize_t cs35l56_debugfs_cal_data_read(struct file *file, + char __user *to, + size_t count, loff_t *ppos) +{ + struct cs35l56_base *cs35l56_base =3D file->private_data; + struct cs35l56_private *cs35l56 =3D cs35l56_private_from_base(cs35l56_bas= e); + struct snd_soc_dapm_context *dapm; + ssize_t ret; + + dapm =3D cs35l56_power_up_for_cal(cs35l56); + if (IS_ERR(dapm)) + return PTR_ERR(dapm); + + ret =3D cs35l56_cal_data_debugfs_read(&cs35l56->base, to, count, ppos); + cs35l56_power_down_after_cal(cs35l56); + + return ret; +} + +static int cs35l56_new_cal_data_apply(struct cs35l56_private *cs35l56) +{ + struct snd_soc_dapm_context *dapm; + int ret; + + if (!cs35l56->base.cal_data_valid) + return -ENXIO; + + if (cs35l56->base.secured) + return -EACCES; + + dapm =3D cs35l56_power_up_for_cal(cs35l56); + if (IS_ERR(dapm)) + return PTR_ERR(dapm); + + snd_soc_dapm_mutex_lock(dapm); + ret =3D cs_amp_write_cal_coeffs(&cs35l56->dsp.cs_dsp, + cs35l56->base.calibration_controls, + &cs35l56->base.cal_data); + if (ret =3D=3D 0) + cs35l56_mbox_send(&cs35l56->base, CS35L56_MBOX_CMD_AUDIO_REINIT); + else + ret =3D -EIO; + + snd_soc_dapm_mutex_unlock(dapm); + cs35l56_power_down_after_cal(cs35l56); + + return ret; +} + +static ssize_t cs35l56_debugfs_cal_data_write(struct file *file, + const char __user *from, + size_t count, loff_t *ppos) +{ + struct cs35l56_base *cs35l56_base =3D file->private_data; + struct cs35l56_private *cs35l56 =3D cs35l56_private_from_base(cs35l56_bas= e); + int ret; + + ret =3D cs35l56_cal_data_debugfs_write(&cs35l56->base, from, count, ppos); + if (ret =3D=3D -ENODATA) + return count; /* Ignore writes of empty cal blobs */ + else if (ret < 0) + return -EIO; + + ret =3D cs35l56_new_cal_data_apply(cs35l56); + if (ret) + return ret; + + return count; +} + +static const struct cs35l56_cal_debugfs_fops cs35l56_cal_debugfs_fops =3D { + .calibrate =3D { + .write =3D cs35l56_debugfs_calibrate_write, + }, + .cal_temperature =3D { + .write =3D cs35l56_debugfs_cal_temperature_write, + }, + .cal_data =3D { + .read =3D cs35l56_debugfs_cal_data_read, + .write =3D cs35l56_debugfs_cal_data_write, + }, +}; + static int cs35l56_set_fw_suffix(struct cs35l56_private *cs35l56) { if (cs35l56->dsp.fwf_suffix) @@ -971,6 +1121,13 @@ static int cs35l56_component_probe(struct snd_soc_com= ponent *component) if (ret) return dev_err_probe(cs35l56->base.dev, ret, "unable to add controls\n"); =20 + ret =3D snd_soc_component_disable_pin(component, "Calibrate"); + if (ret) + return ret; + + if (IS_ENABLED(CONFIG_SND_SOC_CS35L56_CAL_DEBUGFS)) + cs35l56_create_cal_debugfs(&cs35l56->base, &cs35l56_cal_debugfs_fops); + queue_work(cs35l56->dsp_wq, &cs35l56->dsp_work); =20 return 0; @@ -982,6 +1139,8 @@ static void cs35l56_component_remove(struct snd_soc_co= mponent *component) =20 cancel_work_sync(&cs35l56->dsp_work); =20 + cs35l56_remove_cal_debugfs(&cs35l56->base); + if (cs35l56->dsp.cs_dsp.booted) wm_adsp_power_down(&cs35l56->dsp); =20 diff --git a/sound/soc/codecs/cs35l56.h b/sound/soc/codecs/cs35l56.h index 40a1800a4585..4c59f92f3206 100644 --- a/sound/soc/codecs/cs35l56.h +++ b/sound/soc/codecs/cs35l56.h @@ -10,6 +10,7 @@ #define CS35L56_H =20 #include +#include #include #include #include @@ -54,6 +55,11 @@ struct cs35l56_private { u8 sdw_unique_id; }; =20 +static inline struct cs35l56_private *cs35l56_private_from_base(struct cs3= 5l56_base *cs35l56_base) +{ + return container_of(cs35l56_base, struct cs35l56_private, base); +} + extern const struct dev_pm_ops cs35l56_pm_ops_i2c_spi; =20 int cs35l56_system_suspend(struct device *dev); --=20 2.47.3 From nobody Sun Feb 8 07:52:31 2026 Received: from mx0b-001ae601.pphosted.com (mx0b-001ae601.pphosted.com [67.231.152.168]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E77E732D0F4; Tue, 21 Oct 2025 10:50:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=67.231.152.168 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761043840; cv=fail; b=o7O/oOPH8qMcmfFj0QGvVXuc2a3tPxoWPkOr3CoCHSddU9Xvv2ibzmXPhQdKUUOUNzNAg7tT342rg72r/2Pqm1LRYHWyzaxoUqLv2Ni2OhWxthdskRvEHQVAMcMU9oxdYFdbm2LCFsWbpXdGyNrncqVkpnFPg1ta9wWgnYtKMm4= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761043840; c=relaxed/simple; bh=vNdeo2kDj7Ryh/Aa0ZUJG0wVlbRggsECjYI2qF6N9dQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=OQlbXaX7zeMjyqj4geijNtN3SAbH8/oVLJmRWBt7YSJk8ej02FO+UWkxKxiz1zwrFjK4r18EsoSiQJihZLPiqIJmipjvPoEFbqUmUe4xrhgeUMt70sOQt1KvnHKTHYR2IZMsq5REP9MmYUbWBMWxmeK0g8e8Mk3+mYaafPbYiak= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=opensource.cirrus.com; spf=pass smtp.mailfrom=opensource.cirrus.com; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b=Uunsf32+; dkim=pass (1024-bit key) header.d=cirrus4.onmicrosoft.com header.i=@cirrus4.onmicrosoft.com header.b=RaidNR5A; arc=fail smtp.client-ip=67.231.152.168 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=opensource.cirrus.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=opensource.cirrus.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="Uunsf32+"; dkim=pass (1024-bit key) header.d=cirrus4.onmicrosoft.com header.i=@cirrus4.onmicrosoft.com header.b="RaidNR5A" Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 59L9021s941361; Tue, 21 Oct 2025 05:50:34 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s= PODMain02222019; bh=Lc+fzHc8l7r44ynlSUgV2HN8zOPPVS3Lgef4w7M0o78=; b= Uunsf32+oJ5ALwaGXgMhiWSz3R0aqHYQ8MJr9yf5ZyNUtsy89leBwiZobLnA8t89 JHr0BbgxrFetAiEnAa0kioKd/WAZ0iZZzrpLn9FlEd1N/3eqwkZG0zLplAL8uLvW D0uTCQgZ2XzJsoyUG6b6DcZ6B5UM0RWvgY3pJT+jB4TP4GwgdixRlZhPSDLfXbC/ LSI3R17qqBpRhMCzc27I85g1+ABPfxqTZW2ig0a8n2JGl9YaYvz4OOamn9s/VCK4 vCizFUzHjFN6bh9y3MDiFXFjnnR93AY6LKIkcjoO8csXHXvI+QWHHzbB99EnMVWb oEsjZcinaI9hD/PJ93Mr4A== Received: from mw6pr02cu001.outbound.protection.outlook.com (mail-westus2azon11022081.outbound.protection.outlook.com [52.101.48.81]) by mx0b-001ae601.pphosted.com (PPS) with ESMTPS id 49v7aj3eg7-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Tue, 21 Oct 2025 05:50:34 -0500 (CDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=WFCLnc39S+aIv347AeeAt1NhvupGDzumsNNJZqsnRaFto1isaslw8K5AgLg98Kb8E5k5VeJ3dUdHXNcZdrOlcE+nM+Ybz9WQMdCFOGF7oaZTLBtSxvdAUld26y66A/6OerXqXhlgfTHegwW8/3W3ckygF1U0C5a2xH1U8YDY1H1Y0Acyw1xIG33GDigr+yhyIaCtQxzTWvxzTZ7tcfSF+VjFtt21DoSYtlDIRuU10feDcHo7ZD6RJqznqyQdFNr4x69Iq78EqjuGgWSa4hSe8MQgGri3Y/QW8xg9fxZ5SFHXMP8pL0srY/7jmxkaf/9X/8RK+dSMnYBKmDHqAcCOgg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=Lc+fzHc8l7r44ynlSUgV2HN8zOPPVS3Lgef4w7M0o78=; b=kHu3pAZ09cjZ+8079UJufA/RI+jZJ5UYkEqRlne2tXdiQuc1MWzYfA630dUIMFrqnTCT63/xxXck3SM7S9BplXPv5FR9zI+P/50bIkDf+LGI92XcypOhdXpJjtepfhksVtetuPBPCOC9FrWongHbMF2Lmctj00pxC1lGZaIeO5a1BVpF9uOZfRtlT3gCsrAtrQ3yoTDqCGo8jvfsNvL2WxuYlxxwpOYkvOrd0V1DpqzPG8Yu7dIenaJVvHYY1CT584QDEbz2BFUKRkle88+80wOPnW71aeQz0iXN/2AcVLc5QKZ5fE/qHAcs3aKxetNxPTtGvDSfB+aa9ABgwXqkIg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=fail (sender ip is 84.19.233.75) smtp.rcpttodomain=cirrus.com smtp.mailfrom=opensource.cirrus.com; dmarc=fail (p=reject sp=reject pct=100) action=oreject header.from=opensource.cirrus.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus4.onmicrosoft.com; s=selector2-cirrus4-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=Lc+fzHc8l7r44ynlSUgV2HN8zOPPVS3Lgef4w7M0o78=; b=RaidNR5Ai/nBS4w9YsybPkmUDDGZnCbR+BWDHg70OLmutNhabNPvl0F0FCN4v91H0BZoO49jsU+t3Y/HeWM329sRAhroNvxB0aYZJ6iIX/K7bD5EmcM1C+q7EBGTuHudqnridFdRK4OQb16ggKeb8TIeqVaQZoq5AIdVYTeHRY4= Received: from SA9PR03CA0016.namprd03.prod.outlook.com (2603:10b6:806:20::21) by PH7PR19MB7147.namprd19.prod.outlook.com (2603:10b6:510:20e::6) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9228.16; Tue, 21 Oct 2025 10:50:27 +0000 Received: from SA2PEPF000015C9.namprd03.prod.outlook.com (2603:10b6:806:20:cafe::1a) by SA9PR03CA0016.outlook.office365.com (2603:10b6:806:20::21) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9253.12 via Frontend Transport; Tue, 21 Oct 2025 10:50:27 +0000 X-MS-Exchange-Authentication-Results: spf=fail (sender IP is 84.19.233.75) smtp.mailfrom=opensource.cirrus.com; dkim=none (message not signed) header.d=none;dmarc=fail action=oreject header.from=opensource.cirrus.com; Received-SPF: Fail (protection.outlook.com: domain of opensource.cirrus.com does not designate 84.19.233.75 as permitted sender) receiver=protection.outlook.com; client-ip=84.19.233.75; helo=edirelay1.ad.cirrus.com; Received: from edirelay1.ad.cirrus.com (84.19.233.75) by SA2PEPF000015C9.mail.protection.outlook.com (10.167.241.199) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9253.7 via Frontend Transport; Tue, 21 Oct 2025 10:50:26 +0000 Received: from ediswmail9.ad.cirrus.com (ediswmail9.ad.cirrus.com [198.61.86.93]) by edirelay1.ad.cirrus.com (Postfix) with ESMTPS id B1CA8406556; Tue, 21 Oct 2025 10:50:22 +0000 (UTC) Received: from ediswws06.ad.cirrus.com (ediswws06.ad.cirrus.com [198.90.208.24]) by ediswmail9.ad.cirrus.com (Postfix) with ESMTPSA id 7902F822544; Tue, 21 Oct 2025 10:50:22 +0000 (UTC) From: Richard Fitzgerald To: broonie@kernel.org, tiwai@suse.com Cc: linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org, patches@opensource.cirrus.com Subject: [PATCH v2 05/11] ALSA: hda/cs35l56: Create debugfs files for factory calibration Date: Tue, 21 Oct 2025 11:50:16 +0100 Message-ID: <20251021105022.1013685-6-rf@opensource.cirrus.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251021105022.1013685-1-rf@opensource.cirrus.com> References: <20251021105022.1013685-1-rf@opensource.cirrus.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SA2PEPF000015C9:EE_|PH7PR19MB7147:EE_ X-MS-Office365-Filtering-Correlation-Id: fbd5fbc7-058b-4f44-8d64-08de108fa4ea X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|61400799027|36860700013|82310400026|376014; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?tDuxwM4TA8yklPLKv/m5XjeORbd9K7yYI02sosOrjrpdULg27EWkSdVcUjEH?= =?us-ascii?Q?E+b5HoFtAaBK8u6rQyaLanTIioFuJ0TluHfrwt2qLZuCHhIS9lOfUEog5Lm2?= =?us-ascii?Q?kWniVfmJ7zGA86mceQln4OpjVo6O7LuZmuYH6QkW64FdfAQ0aN8QdiOSYcD6?= =?us-ascii?Q?4vrIvxE2FT/+yJi1+C4k1NfXrDbx0GJNLyC3S0zO1CbnWmmWmJNshg9V0QDH?= =?us-ascii?Q?vtxKguntlLDatEHGt8sirhBhVfjPyXRehw0Ono0NzUCwFlFoA9FzXqeWUA16?= =?us-ascii?Q?xDaVIDyfC+igkqfQWauK8wOiz3EeqVix/Lx1l61pCL86ALCAt3dlKjFBg7PU?= =?us-ascii?Q?HVoZ+sXgD1Xv0DQpv2z+qmzODSy/mkKCz1F5ds4ly9iAvSAnv5eWS7GuZSma?= =?us-ascii?Q?g3V3LnF0aUjHyTEA4/23/NnvAYR/kQRSI/C0WMGzRJCWAFLlilrGPK33G6S4?= =?us-ascii?Q?Odo7bn+VEJEFfh7k1DBz/6nIuqgyeAnRXvB+LmmEKaMqNyMFA0mNN5nPEfRV?= =?us-ascii?Q?zyPMOgoGt6QsDZKyfzuP+L7RGf9zZxOBw3RnKPJXK+gYf3ecAa2Sub6maFoX?= =?us-ascii?Q?HbT1xHlQc2j9pV5cz7Ry8i4kZj5cw7+h2D9dT8JAypCWO109bmIgFW5rdWDA?= =?us-ascii?Q?NWthJpyOP20y0zGw4YFSSXyFb2ccEFng6WS/vqizAXC1uc8GCi/Ufbhspzy5?= =?us-ascii?Q?5OfWbqL3gYGajPOiRAJpkDKffzqU0R1zdOetYh7+dpwYXW5FjDoTxAw197LS?= =?us-ascii?Q?Eom336z7Lx8FQ1Go7+njdwDiLxQkut6/TjayvdlHqYuGNqKCNu1c6myQEpNy?= =?us-ascii?Q?bNViIRG6RiPBgsbeOjAl5nwI9uGPjHtzqrvne/YYziy/MG6PQLGfs3eDyEUq?= =?us-ascii?Q?ND6LlBYwjGO941zSRgC6dvTYncg3TZenH46IGk8/vl9QWG8Q08qd/cAexpl3?= =?us-ascii?Q?o8Z+FB3+axSs1j1tn0xi7EyTjLMykGuBjfngpHFdsFe6J9/LUqrJwVyDooXP?= =?us-ascii?Q?D9Xk7pkTFzwtHTXilvCmh+Qy59HMiEkndxEVf1jKPhUEjEYN+mtuGmPvFnau?= =?us-ascii?Q?Hqq5I14UXkU51GfubZWNd1G00hh0x8XfhjuOOeQ1zAl5YtL4iyd2qUoxFLWf?= =?us-ascii?Q?7PZ3+DyWtoyg33z+KuOe5Ot4mEZaNwt7hKbX99vVAQ5ncwRDyzZSEWOQ+kjn?= =?us-ascii?Q?WSHhW/Ac2wHdqKg20wmkcGn9f9s0ouKnBN5hMF0CqVQ2CI+U76w7+Cv3jBwD?= =?us-ascii?Q?214rCo88LWNG/5BZpepIQUc24+7dIkJzlNAnGb1UCrfvARGCNSaVr5LMtljc?= =?us-ascii?Q?Oh4XNkubXkduHsXSLSRRPpkLvqbGkdXS7LWdIs1Dl+eYqYMmSONqN3F208xG?= =?us-ascii?Q?LsYnaGC7g6qmJIS9ZNJaWB1ml/QiofWsNAMfShsE7IKU+ifpctmmwmphwscr?= =?us-ascii?Q?X71oe09ri3d/r/arZ5u6Pcbfbca1x92aim2ZOKKSr+ZiWcrXMtW3/U4AmbDE?= =?us-ascii?Q?Hr044DO/zjN3aQpNE5+shL/z7uOG4Ccs70t6CQMHwPPG2XwFLtczxID7bmGE?= =?us-ascii?Q?8Geec7b0xI5rC0UqguY=3D?= X-Forefront-Antispam-Report: CIP:84.19.233.75;CTRY:GB;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:edirelay1.ad.cirrus.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(61400799027)(36860700013)(82310400026)(376014);DIR:OUT;SFP:1102; X-OriginatorOrg: opensource.cirrus.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Oct 2025 10:50:26.3642 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: fbd5fbc7-058b-4f44-8d64-08de108fa4ea X-MS-Exchange-CrossTenant-Id: bec09025-e5bc-40d1-a355-8e955c307de8 X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=bec09025-e5bc-40d1-a355-8e955c307de8;Ip=[84.19.233.75];Helo=[edirelay1.ad.cirrus.com] X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: TreatMessagesAsInternal-SA2PEPF000015C9.namprd03.prod.outlook.com X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH7PR19MB7147 X-Proofpoint-ORIG-GUID: IQOstCMNpTJwLVIS8XNHYG_GoepQ6-hb X-Proofpoint-GUID: IQOstCMNpTJwLVIS8XNHYG_GoepQ6-hb X-Authority-Analysis: v=2.4 cv=bdNmkePB c=1 sm=1 tr=0 ts=68f7657a cx=c_pps a=OvjpmfG2phmKxcO1Hl3QmQ==:117 a=h1hSm8JtM9GN1ddwPAif2w==:17 a=6eWqkTHjU83fiwn7nKZWdM+Sl24=:19 a=z/mQ4Ysz8XfWz/Q5cLBRGdckG28=:19 a=x6icFKpwvdMA:10 a=s63m1ICgrNkA:10 a=RWc_ulEos4gA:10 a=VkNPw1HP01LnGYTKEx00:22 a=w1d2syhTAAAA:8 a=cVLFTHSKG9q2iFVCogsA:9 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMDIxMDA4NSBTYWx0ZWRfXzLIURoU0Hlz8 MG+PZnzlFmx/EwiiSJK9y+98mVXFyoKkr4mS4db2ty+Dj8TZdszwy4SSZJTDvrR5gCv0H8mj3IC aybBW7pWDA8i3R5JNZ5tD9kFQ57X7nYXBjHv9JcnS47szsTJUvV9+er542dhDH2WGWu1FXrsAmk S/YvR42DlXovZ++6gGlFKLLY9sxCdDOn2VNXicu3kl+25LpzwJ+VqPTsoSUT052ScvJ4P9Gszrz to7Ee5mm4eI5+u6CScNeugdOA+tJCirgCQxl0FDD1UcljvIcOsvYSdTXeyMfZKdie0ufioMw6dj Ln6uukTUIG9NpxcfiIHpi+9Hsofts3AW/Z3JN7YnqO1SZe1PsnZ7jHJf3y4KNHHQq1EDfpkA2cE rMOjgTADsX48eUgB6sUx5hTOEBVVqw== X-Proofpoint-Spam-Reason: safe Content-Type: text/plain; charset="utf-8" Create debugfs files that can be used to perform factory calibration. During manufacture, the production line must perform a factory calibration of the amps. This commit adds this functionality via debugfs files. As this is only needed during manufacture, there is no need for this to be available in a normal system so a Kconfig item has been added to enable this. The new Kconfig option is inside a sub-menu because items do not group and indent if the parent is invisible or there are multiple parent dependencies. Anyway the sub-menu reduces the clutter. cs35l56_hda_apply_calibration() has been changed to return an error code that can be reported back through the debugfs write. The original call to this function doesn't check the return code because in normal use it doesn't matter whether this fails - the firmware will default to a safe calibration for the platform. But tooling using the debugfs files might want to know if there was an error. Signed-off-by: Richard Fitzgerald Reviewed-by: Takashi Iwai --- Changes in V2: - File callbacks rewritten to be debugfs callbacks instead of sysfs callbacks. - Replace the sysfs file definition and creation with debugfs creation. sound/hda/codecs/side-codecs/Kconfig | 15 +++ sound/hda/codecs/side-codecs/cs35l56_hda.c | 114 ++++++++++++++++++++- sound/hda/codecs/side-codecs/cs35l56_hda.h | 6 ++ 3 files changed, 130 insertions(+), 5 deletions(-) diff --git a/sound/hda/codecs/side-codecs/Kconfig b/sound/hda/codecs/side-c= odecs/Kconfig index cbf1847896bc..f674e9a9c7d7 100644 --- a/sound/hda/codecs/side-codecs/Kconfig +++ b/sound/hda/codecs/side-codecs/Kconfig @@ -88,6 +88,21 @@ config SND_HDA_SCODEC_CS35L56_SPI Say Y or M here to include CS35L56 amplifier support with SPI control. =20 +menu "CS35L56 driver options" + depends on SND_HDA_SCODEC_CS35L56 + +config SND_HDA_SCODEC_CS35L56_CAL_DEBUGFS + bool "CS35L56 create debugfs for factory calibration" + default N + depends on DEBUG_FS + select SND_SOC_CS35L56_CAL_DEBUGFS_COMMON + help + Create debugfs entries used during factory-line manufacture + for factory calibration. + + If unsure select "N". +endmenu + config SND_HDA_SCODEC_TAS2781 tristate select SND_HDA_GENERIC diff --git a/sound/hda/codecs/side-codecs/cs35l56_hda.c b/sound/hda/codecs/= side-codecs/cs35l56_hda.c index 5bb1c4ebeaf3..03f565312459 100644 --- a/sound/hda/codecs/side-codecs/cs35l56_hda.c +++ b/sound/hda/codecs/side-codecs/cs35l56_hda.c @@ -548,20 +548,24 @@ static void cs35l56_hda_release_firmware_files(const = struct firmware *wmfw_firmw kfree(coeff_filename); } =20 -static void cs35l56_hda_apply_calibration(struct cs35l56_hda *cs35l56) +static int cs35l56_hda_apply_calibration(struct cs35l56_hda *cs35l56) { int ret; =20 if (!cs35l56->base.cal_data_valid || cs35l56->base.secured) - return; + return -EACCES; =20 ret =3D cs_amp_write_cal_coeffs(&cs35l56->cs_dsp, &cs35l56_calibration_controls, &cs35l56->base.cal_data); - if (ret < 0) + if (ret < 0) { dev_warn(cs35l56->base.dev, "Failed to write calibration: %d\n", ret); - else - dev_info(cs35l56->base.dev, "Calibration applied\n"); + return ret; + } + + dev_info(cs35l56->base.dev, "Calibration applied\n"); + + return 0; } =20 static void cs35l56_hda_fw_load(struct cs35l56_hda *cs35l56) @@ -669,7 +673,9 @@ static void cs35l56_hda_fw_load(struct cs35l56_hda *cs3= 5l56) if (ret) dev_dbg(cs35l56->base.dev, "%s: cs_dsp_run ret %d\n", __func__, ret); =20 + /* Don't need to check return code, it's not fatal if this fails */ cs35l56_hda_apply_calibration(cs35l56); + ret =3D cs35l56_mbox_send(&cs35l56->base, CS35L56_MBOX_CMD_AUDIO_REINIT); if (ret) cs_dsp_stop(&cs35l56->cs_dsp); @@ -695,6 +701,100 @@ static void cs35l56_hda_dsp_work(struct work_struct *= work) cs35l56_hda_fw_load(cs35l56); } =20 +static ssize_t cs35l56_hda_debugfs_calibrate_write(struct file *file, + const char __user *from, + size_t count, loff_t *ppos) +{ + struct cs35l56_base *cs35l56_base =3D file->private_data; + ssize_t ret; + + ret =3D pm_runtime_resume_and_get(cs35l56_base->dev); + if (ret) + return ret; + + ret =3D cs35l56_calibrate_debugfs_write(cs35l56_base, from, count, ppos); + pm_runtime_autosuspend(cs35l56_base->dev); + + return ret; +} + +static ssize_t cs35l56_hda_debugfs_cal_temperature_write(struct file *file, + const char __user *from, + size_t count, loff_t *ppos) +{ + struct cs35l56_base *cs35l56_base =3D file->private_data; + ssize_t ret; + + ret =3D pm_runtime_resume_and_get(cs35l56_base->dev); + if (ret) + return ret; + + ret =3D cs35l56_cal_ambient_debugfs_write(cs35l56_base, from, count, ppos= ); + pm_runtime_autosuspend(cs35l56_base->dev); + + return ret; +} + +static ssize_t cs35l56_hda_debugfs_cal_data_read(struct file *file, + char __user *to, + size_t count, loff_t *ppos) +{ + struct cs35l56_base *cs35l56_base =3D file->private_data; + ssize_t ret; + + ret =3D pm_runtime_resume_and_get(cs35l56_base->dev); + if (ret) + return ret; + + ret =3D cs35l56_cal_data_debugfs_read(cs35l56_base, to, count, ppos); + pm_runtime_autosuspend(cs35l56_base->dev); + + return ret; +} + +static ssize_t cs35l56_hda_debugfs_cal_data_write(struct file *file, + const char __user *from, + size_t count, loff_t *ppos) +{ + struct cs35l56_base *cs35l56_base =3D file->private_data; + struct cs35l56_hda *cs35l56 =3D cs35l56_hda_from_base(cs35l56_base); + ssize_t ret; + + ret =3D cs35l56_cal_data_debugfs_write(cs35l56_base, from, count, ppos); + if (ret =3D=3D -ENODATA) + return count; /* Ignore writes of empty cal blobs */ + + if (ret < 0) + return ret; + + ret =3D pm_runtime_resume_and_get(cs35l56_base->dev); + if (ret) + return ret; + + ret =3D cs35l56_hda_apply_calibration(cs35l56); + if (ret =3D=3D 0) + cs35l56_mbox_send(cs35l56_base, CS35L56_MBOX_CMD_AUDIO_REINIT); + else + count =3D -EIO; + + pm_runtime_autosuspend(cs35l56_base->dev); + + return count; +} + +static const struct cs35l56_cal_debugfs_fops cs35l56_hda_cal_debugfs_fops = =3D { + .calibrate =3D { + .write =3D cs35l56_hda_debugfs_calibrate_write, + }, + .cal_temperature =3D { + .write =3D cs35l56_hda_debugfs_cal_temperature_write, + }, + .cal_data =3D { + .read =3D cs35l56_hda_debugfs_cal_data_read, + .write =3D cs35l56_hda_debugfs_cal_data_write, + }, +}; + static int cs35l56_hda_bind(struct device *dev, struct device *master, voi= d *master_data) { struct cs35l56_hda *cs35l56 =3D dev_get_drvdata(dev); @@ -722,6 +822,9 @@ static int cs35l56_hda_bind(struct device *dev, struct = device *master, void *mas cs_dsp_init_debugfs(&cs35l56->cs_dsp, cs35l56->debugfs_root); #endif =20 + if (IS_ENABLED(CONFIG_SND_HDA_SCODEC_CS35L56_CAL_DEBUGFS)) + cs35l56_create_cal_debugfs(&cs35l56->base, &cs35l56_hda_cal_debugfs_fops= ); + dev_dbg(cs35l56->base.dev, "Bound\n"); =20 return 0; @@ -735,6 +838,7 @@ static void cs35l56_hda_unbind(struct device *dev, stru= ct device *master, void * =20 cancel_work_sync(&cs35l56->dsp_work); =20 + cs35l56_remove_cal_debugfs(&cs35l56->base); cs35l56_hda_remove_controls(cs35l56); =20 #if IS_ENABLED(CONFIG_SND_DEBUG) diff --git a/sound/hda/codecs/side-codecs/cs35l56_hda.h b/sound/hda/codecs/= side-codecs/cs35l56_hda.h index 38d94fb213a5..cb4b5e7356a3 100644 --- a/sound/hda/codecs/side-codecs/cs35l56_hda.h +++ b/sound/hda/codecs/side-codecs/cs35l56_hda.h @@ -9,6 +9,7 @@ #ifndef __CS35L56_HDA_H__ #define __CS35L56_HDA_H__ =20 +#include #include #include #include @@ -42,6 +43,11 @@ struct cs35l56_hda { #endif }; =20 +static inline struct cs35l56_hda *cs35l56_hda_from_base(struct cs35l56_bas= e *cs35l56_base) +{ + return container_of(cs35l56_base, struct cs35l56_hda, base); +} + extern const struct dev_pm_ops cs35l56_hda_pm_ops; =20 int cs35l56_hda_common_probe(struct cs35l56_hda *cs35l56, int hid, int id); --=20 2.47.3 From nobody Sun Feb 8 07:52:31 2026 Received: from mx0b-001ae601.pphosted.com (mx0a-001ae601.pphosted.com [67.231.149.25]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9F48D32AAD2; Tue, 21 Oct 2025 10:50:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=67.231.149.25 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761043837; cv=fail; b=uonyTNkT0a9SEZshGFYSanYZAOZUEfFfIVstCvmmZTccgIhimXak/Pk2tFsPIodLKLio+tdh129y0XgYNlXd4cLuljg+tXg2badCOrhIMOuQz+gS36145eutjRc49NjgFv7cHkvYA9s42TNqQ7hWUwaK+hGfu9nzj7n5wnu2ICI= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761043837; c=relaxed/simple; bh=5AXriAOEXg4ph11wWq2D48nBeokCKrLu7FlO4H/a0HI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=j0QyUcIJmigRVKvvZbXuzGDZLvskj5mO21KDO0XauAzb9uf7sH1ps3HVwATt5b4P6rGISTNkNv/wIbD04IC5iqCw0sn0J1tkvdrDbuMfkGZDHyfuWuzThqIS3cUNCKeg2A5ldeLk+Jk1CIN9GldlnYMnwpjcvYV+YXoRJ4mYQYU= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=opensource.cirrus.com; spf=pass smtp.mailfrom=opensource.cirrus.com; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b=MJQ6ihO6; dkim=pass (1024-bit key) header.d=cirrus4.onmicrosoft.com header.i=@cirrus4.onmicrosoft.com header.b=iegHYSU2; arc=fail smtp.client-ip=67.231.149.25 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=opensource.cirrus.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=opensource.cirrus.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="MJQ6ihO6"; dkim=pass (1024-bit key) header.d=cirrus4.onmicrosoft.com header.i=@cirrus4.onmicrosoft.com header.b="iegHYSU2" Received: from pps.filterd (m0077473.ppops.net [127.0.0.1]) by mx0a-001ae601.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 59L5824B988201; Tue, 21 Oct 2025 05:50:31 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s= PODMain02222019; bh=BfXbS79G3ctaThncG4NMQkfeIrMFbOISXRpBpKSZioM=; b= MJQ6ihO6pW6fPT3dykcPJslRXs1KxWdaco1FDi9e1kmVeVQUFmxIVW2uGMTQyrhD 2nYCcvLHqRcQP83W+UBQwMDavDyXFzy5sxxTvFSRuC4n5W/YOqJ/ZPhtlSyyIBmF Nrnr8nmDavcwh44ZBKYzM1JRqIlCsge33vwROA7e3z06V1VvX4cSJ4W2GqdzclnX +dVVQ94IvcBLAWW7TyI47bMuNbz+KNH/3eQTIomQJBlUD8gPGpBoG2d2wfvDD89q /ZySsUVKz0wvKhHZkJQR3aPvSIUp5xRLgXHpgCtfyoqqTaqgCkHvHOGT09GZ2waz 8W8/bHnqoaRRF7CIUThu0g== Received: from bl0pr03cu003.outbound.protection.outlook.com (mail-eastusazon11022114.outbound.protection.outlook.com [52.101.53.114]) by mx0a-001ae601.pphosted.com (PPS) with ESMTPS id 49wnc4sdqk-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Tue, 21 Oct 2025 05:50:31 -0500 (CDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=x+hWc+wRGruywDRorqFNm7nRXfIXXMoc8N0DOb7DewgXxp9+pvow0CBcFCIOUotqSautXRiEIh0siRrofg5B7Jt8mXtc2PfgD8G4HOZ9RlTQMV9PrhD6XLbmNCpCYbHVsxHZOwXF+1Mel5f5RXHWYinxhuMVeXodcGssw1XHpARSBFfjP4KCLoPmkY+YuM49IN9hfweLfEo5xHZkxZQPfPSLvFYUTXgtidCBv0AdCibOlEDl+EpM0l7KH8YmeYs8LyqAntq5sS+yrUOiT/8EU9qatIuRQog81moADjaz4sTlmAdLSlp5vIpHUZyEeKsF1OzMzmynI5dhjuCcfsoq5w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=BfXbS79G3ctaThncG4NMQkfeIrMFbOISXRpBpKSZioM=; b=PzeEdsNOxg9Bk5Lb3ZTRj8fOXtIARQitVdoMr1nGrRL1Js3KmKy5qdjxMBWMdk6UMpcwy5BpNZXJrdbY4iVvBN9zXr4+vTY938Pf6QUL2FTipkW290larmfmDWW/WvCDlF9D1nLba6YVPHd0frtGh9Ja+CEN7zZi5EMx/87fAs6HyX+T8ga9TegZAZRX5lfTvaPuN4/iQsL8nnskZCp6CfAoERdGbqr4cXAy5TPU5GwsKkCOY0GMVzPA1ahQimT+Q8zIzKKkn3PkYMwhk1CcryQlPa4YzeQwGNpKWbEyVFpWCu1x43/qaTSMyLgokpxz13nvLbElFZEqy6KydPj8wg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=fail (sender ip is 84.19.233.75) smtp.rcpttodomain=cirrus.com smtp.mailfrom=opensource.cirrus.com; dmarc=fail (p=reject sp=reject pct=100) action=oreject header.from=opensource.cirrus.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus4.onmicrosoft.com; s=selector2-cirrus4-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=BfXbS79G3ctaThncG4NMQkfeIrMFbOISXRpBpKSZioM=; b=iegHYSU2MZE7ptuR8BqnyYQiPoxerpoZ4lzN1TVmSgvnjwjcqWME1mSN2tppmQptdPb5nrFUP7ia6oLvEAlA952Yli0AUTKmTtt6jmLWZMye+hVT7dg4DRjBW7iF3SHiBdmWG8xwgiZBVXvjF2RsEtf2JM8/GGvj8fYWatubXH4= Received: from BYAPR21CA0026.namprd21.prod.outlook.com (2603:10b6:a03:114::36) by PH8PR19MB6715.namprd19.prod.outlook.com (2603:10b6:510:1ca::12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9228.16; Tue, 21 Oct 2025 10:50:28 +0000 Received: from SJ1PEPF000023D0.namprd02.prod.outlook.com (2603:10b6:a03:114:cafe::93) by BYAPR21CA0026.outlook.office365.com (2603:10b6:a03:114::36) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9275.4 via Frontend Transport; Tue, 21 Oct 2025 10:50:28 +0000 X-MS-Exchange-Authentication-Results: spf=fail (sender IP is 84.19.233.75) smtp.mailfrom=opensource.cirrus.com; dkim=none (message not signed) header.d=none;dmarc=fail action=oreject header.from=opensource.cirrus.com; Received-SPF: Fail (protection.outlook.com: domain of opensource.cirrus.com does not designate 84.19.233.75 as permitted sender) receiver=protection.outlook.com; client-ip=84.19.233.75; helo=edirelay1.ad.cirrus.com; Received: from edirelay1.ad.cirrus.com (84.19.233.75) by SJ1PEPF000023D0.mail.protection.outlook.com (10.167.244.4) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9253.7 via Frontend Transport; Tue, 21 Oct 2025 10:50:26 +0000 Received: from ediswmail9.ad.cirrus.com (ediswmail9.ad.cirrus.com [198.61.86.93]) by edirelay1.ad.cirrus.com (Postfix) with ESMTPS id B3BC7406559; Tue, 21 Oct 2025 10:50:22 +0000 (UTC) Received: from ediswws06.ad.cirrus.com (ediswws06.ad.cirrus.com [198.90.208.24]) by ediswmail9.ad.cirrus.com (Postfix) with ESMTPSA id 7C9C6822545; Tue, 21 Oct 2025 10:50:22 +0000 (UTC) From: Richard Fitzgerald To: broonie@kernel.org, tiwai@suse.com Cc: linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org, patches@opensource.cirrus.com Subject: [PATCH v2 06/11] ASoC: cs-amp-lib-test: Add cases for factory calibration helpers Date: Tue, 21 Oct 2025 11:50:17 +0100 Message-ID: <20251021105022.1013685-7-rf@opensource.cirrus.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251021105022.1013685-1-rf@opensource.cirrus.com> References: <20251021105022.1013685-1-rf@opensource.cirrus.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ1PEPF000023D0:EE_|PH8PR19MB6715:EE_ X-MS-Office365-Filtering-Correlation-Id: d4e67546-0660-4ce5-deb3-08de108fa53a X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|36860700013|61400799027|376014|82310400026; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?0qDK5xl4Rh2Fh2WJTEId2uedSIe+dfj59CP/1maJ9pKE4n1IaeagJkfN6OqX?= =?us-ascii?Q?YXR8pVP0q/qTQGwC70F09pBTMAl90Q25aBGr1Z7DlEyB0gGMCdpvxzywQR5l?= =?us-ascii?Q?yeMg46t926W1t3QQH6ogqNsEosKss44kIrb6eNWmjD8IlffzsBD5sln19GYV?= =?us-ascii?Q?+uCiT9JasvOWE865pBCIQKVogKKFK+cAW5T1qB17+R7Wq90aDJ7wi0NNr3dw?= =?us-ascii?Q?ahomHVQLAKAjPj30svWv+JWF9ynZH9zk4pDt8FkSjQNvb79kQBtHl1LrtVtc?= =?us-ascii?Q?Vhmp8GDijs+RpIlUO6fO4a0blgPSjp538RgoLd5456kdgIVMAP96MoFCD/7N?= =?us-ascii?Q?yQlFlBCR0+gRd3hZtRhpBSmrIRgDODlhpOYmmkT4WCisaBY/elrS23mf74wi?= =?us-ascii?Q?eUMyJlQgGY4eDE9wAbulO5bonFnfMHOR2zM6CT2VX5VbnIctkRKMHS/7XsXQ?= =?us-ascii?Q?3HaQ9FpQTLQpDiBa7Tot85HLcal1mckQHmVHhH5bsb3D3q8Y6EU4NooWYRlB?= =?us-ascii?Q?FKqZZCOSLSj5qOmitW8n+afF8PF7vuacZ9nbTWbnNZkwq99kkR8rQZ1jFw/9?= =?us-ascii?Q?pH6LoELldGvJvz8nuOYDi7aEwXbuUkqo36zdo9JSloOsqdB+PleNT/su0dSq?= =?us-ascii?Q?QdFHRV26lWX8NsWszsf+uf7EEZ9UtsJM9agJ6aqCqK+wdsm3+gZXLTOmI1j+?= =?us-ascii?Q?iB8yF5z42VePGXFsouue3uLOYm1nlRk/YlAGAndfqYxBcb6CaL5KhcKhj9/F?= =?us-ascii?Q?BOOF90DwDs7xVSkDY0ZbaPdiK1d8agCd7vvYAOzFyNVO+vXUV4UAxeZl/a/B?= =?us-ascii?Q?fRnTOltd4pRa+A/iMTfzNi4jBwMkBwjjiNN23DaBdN6oz1GRuLB7BxUMci/7?= =?us-ascii?Q?O0QwZYZaIt6m6TW8vxQc/lSHfEGsm2P+ewc3zA+bMCd8UaPJHCs6x/GW3cGM?= =?us-ascii?Q?xyAg9l1B/sE45j77vZN8dn82Qe8RrGdwhUOfkcCTqJ5ilULmZ6o9TQjoyNEm?= =?us-ascii?Q?QWOC1t4GAFWNkLz+ZKxGy0I8jNh0NAh99p8mEwbtltJTXK4O7OHcGk+I39Rj?= =?us-ascii?Q?CmoewPVlogxtGO3rRCDERScXDJTiRQb4TlOahsF6mcapctT1fyOnCfwniQSx?= =?us-ascii?Q?6rooqkEI6Cn1utoI2Gq42hRFiM8QQRdj5nDK/GXEq/2Goch+ZxUcFPnEcDpp?= =?us-ascii?Q?260IUesF4uiLad6FsVeLfzJUzMsWYCqMIFpByAORcpACeCzML2/LicGSxPNi?= =?us-ascii?Q?+jVTrHTliK7Gss2JH9kIpOCAysqE6/VHDacSxN1awGJihRq06Lxqc1g0R77+?= =?us-ascii?Q?kzSZL60SNFmcRs9EcJ8/AeO2w7qOKOELz5qjqeUGXMr+AM5ywfMqyW3R/kOI?= =?us-ascii?Q?6/dibI2TTUT2v6x3KxYdUbqnowGlgsWh1EEJd3xrim0dwm6uQtclhH7yvFh7?= =?us-ascii?Q?NzNI4oonNvLRyGUxUA9onQBESl3zpKEDCG4c5zFRAgB3y+FaRsNHl0Qu3qJO?= =?us-ascii?Q?ShnhChSC8IW46IKkxYjmQ2bS9jK8cP3c8K6kLFD6x291e5peld9S9TvdGw32?= =?us-ascii?Q?3opJ4buNqJVNlCzG49o=3D?= X-Forefront-Antispam-Report: CIP:84.19.233.75;CTRY:GB;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:edirelay1.ad.cirrus.com;PTR:ErrorRetry;CAT:NONE;SFS:(13230040)(36860700013)(61400799027)(376014)(82310400026);DIR:OUT;SFP:1102; X-OriginatorOrg: opensource.cirrus.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Oct 2025 10:50:26.8307 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: d4e67546-0660-4ce5-deb3-08de108fa53a X-MS-Exchange-CrossTenant-Id: bec09025-e5bc-40d1-a355-8e955c307de8 X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=bec09025-e5bc-40d1-a355-8e955c307de8;Ip=[84.19.233.75];Helo=[edirelay1.ad.cirrus.com] X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: TreatMessagesAsInternal-SJ1PEPF000023D0.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH8PR19MB6715 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMDIxMDA4NSBTYWx0ZWRfXwbvx3AxT4A2a eyoNtVoM687tUaerPUN+/n1h5H5jfVAiejbnj5xJu0UbGWQ3A76U0s8BLPoqcmOgtYxSCB+HnLo iNISxnTad8cSUrfmA5uuHlbEEQJykCJu9/fjkiaxqetgiJhh8+oTYpEl7dsc6NqKDqM9LVMf6vw Mq7eCN4f1DWaQmJuGrS9O71985+h8J1ggFVZp1bJu0wn2XUmmoPCkCZkczqr8y2QW6Eqks8dmaV enM+7LYJszL3sADd1LAqTdB7qca1Pgs0SiyzFUDU4N1BxBwZVjK02dsvbCdH5jRAU0NsUdACMLt wJo01rs6HrUujgTDbEUGNqmXYbu6FoU2FuCLkEYZosc60Z54/N9fkKwiWTpQ9npRJzPvYVtmhZY k+DQMjB79G5ZVGtdPTNuahlJnv7Tlw== X-Proofpoint-GUID: WwNT4A3BCrXJpUFuWBXzP5nO6kH7KYJL X-Proofpoint-ORIG-GUID: WwNT4A3BCrXJpUFuWBXzP5nO6kH7KYJL X-Authority-Analysis: v=2.4 cv=bf1mkePB c=1 sm=1 tr=0 ts=68f76577 cx=c_pps a=PPij9JC9dsFwf49xmEs+Gw==:117 a=h1hSm8JtM9GN1ddwPAif2w==:17 a=6eWqkTHjU83fiwn7nKZWdM+Sl24=:19 a=z/mQ4Ysz8XfWz/Q5cLBRGdckG28=:19 a=x6icFKpwvdMA:10 a=RWc_ulEos4gA:10 a=VkNPw1HP01LnGYTKEx00:22 a=w1d2syhTAAAA:8 a=tIIsFs4PSpDOh4qjPvUA:9 X-Proofpoint-Spam-Reason: safe Content-Type: text/plain; charset="utf-8" Add test cases for the cs_amp_read_cal_coeffs() and cs_amp_write_ambient_temp() functions. In both cases the test is simply to confirm that the correct data value(s) get passed back to the caller. Signed-off-by: Richard Fitzgerald Reviewed-by: Takashi Iwai --- No changes since V1. include/sound/cs-amp-lib.h | 5 +- sound/soc/codecs/cs-amp-lib-test.c | 75 +++++++++++++++++++++++++++++- sound/soc/codecs/cs-amp-lib.c | 1 + 3 files changed, 79 insertions(+), 2 deletions(-) diff --git a/include/sound/cs-amp-lib.h b/include/sound/cs-amp-lib.h index 5b094f8e8a6f..efa744133a35 100644 --- a/include/sound/cs-amp-lib.h +++ b/include/sound/cs-amp-lib.h @@ -72,8 +72,11 @@ struct cs_amp_test_hooks { int (*write_cal_coeff)(struct cs_dsp *dsp, const struct cirrus_amp_cal_controls *controls, const char *ctl_name, u32 val); -}; =20 + int (*read_cal_coeff)(struct cs_dsp *dsp, + const struct cirrus_amp_cal_controls *controls, + const char *ctl_name, u32 *val); +}; extern const struct cs_amp_test_hooks * const cs_amp_test_hooks; =20 #endif /* CS_AMP_LIB_H */ diff --git a/sound/soc/codecs/cs-amp-lib-test.c b/sound/soc/codecs/cs-amp-l= ib-test.c index 2fde84309338..6878941a8f57 100644 --- a/sound/soc/codecs/cs-amp-lib-test.c +++ b/sound/soc/codecs/cs-amp-lib-test.c @@ -701,6 +701,77 @@ static void cs_amp_lib_test_write_cal_data_test(struct= kunit *test) KUNIT_EXPECT_EQ(test, entry->value, data.calStatus); } =20 +static int cs_amp_lib_test_read_cal_coeff(struct cs_dsp *dsp, + const struct cirrus_amp_cal_controls *controls, + const char *ctl_name, u32 *val) +{ + struct kunit *test =3D kunit_get_current_test(); + + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctl_name); + KUNIT_EXPECT_PTR_EQ(test, controls, &cs_amp_lib_test_calibration_controls= ); + + if (strcmp(ctl_name, controls->ambient) =3D=3D 0) + *val =3D 19; + else if (strcmp(ctl_name, controls->calr) =3D=3D 0) + *val =3D 1077; + else if (strcmp(ctl_name, controls->status) =3D=3D 0) + *val =3D 2; + else + kunit_fail_current_test("Bad control '%s'\n", ctl_name); + + return 0; +} + +static void cs_amp_lib_test_read_cal_data_test(struct kunit *test) +{ + struct cs_amp_lib_test_priv *priv =3D test->priv; + struct cirrus_amp_cal_data data =3D { 0 }; + struct cs_dsp *dsp; + int ret; + + dsp =3D kunit_kzalloc(test, sizeof(*dsp), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dsp); + dsp->dev =3D &priv->amp_dev->dev; + + kunit_activate_static_stub(test, + cs_amp_test_hooks->read_cal_coeff, + cs_amp_lib_test_read_cal_coeff); + + ret =3D cs_amp_read_cal_coeffs(dsp, &cs_amp_lib_test_calibration_controls= , &data); + KUNIT_EXPECT_EQ(test, ret, 0); + + KUNIT_EXPECT_EQ(test, 19, data.calAmbient); + KUNIT_EXPECT_EQ(test, 1077, data.calR); + KUNIT_EXPECT_EQ(test, 2, data.calStatus); + KUNIT_EXPECT_NE(test, 0, data.calTime[0] | data.calTime[1]); +} + +static void cs_amp_lib_test_write_ambient_test(struct kunit *test) +{ + struct cs_amp_lib_test_priv *priv =3D test->priv; + struct cs_amp_lib_test_ctl_write_entry *entry; + struct cs_dsp *dsp; + int ret; + + dsp =3D kunit_kzalloc(test, sizeof(*dsp), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dsp); + dsp->dev =3D &priv->amp_dev->dev; + + /* Redirect calls to write firmware controls */ + kunit_activate_static_stub(test, + cs_amp_test_hooks->write_cal_coeff, + cs_amp_lib_test_write_cal_coeff); + + ret =3D cs_amp_write_ambient_temp(dsp, &cs_amp_lib_test_calibration_contr= ols, 18); + KUNIT_EXPECT_EQ(test, ret, 0); + + KUNIT_EXPECT_EQ(test, list_count_nodes(&priv->ctl_write_list), 1); + + entry =3D list_first_entry(&priv->ctl_write_list, typeof(*entry), list); + KUNIT_EXPECT_STREQ(test, entry->name, cs_amp_lib_test_calibration_control= s.ambient); + KUNIT_EXPECT_EQ(test, entry->value, 18); +} + static void cs_amp_lib_test_spkid_lenovo_not_present(struct kunit *test) { struct cs_amp_lib_test_priv *priv =3D test->priv; @@ -973,8 +1044,10 @@ static struct kunit_case cs_amp_lib_test_cases[] =3D { cs_amp_lib_test_get_cal_gen_params), KUNIT_CASE(cs_amp_lib_test_get_efi_cal_empty_entry_test), =20 - /* Tests for writing calibration data */ + /* Tests for writing and reading calibration data */ KUNIT_CASE(cs_amp_lib_test_write_cal_data_test), + KUNIT_CASE(cs_amp_lib_test_read_cal_data_test), + KUNIT_CASE(cs_amp_lib_test_write_ambient_test), =20 /* Test cases for speaker ID */ KUNIT_CASE(cs_amp_lib_test_spkid_lenovo_not_present), diff --git a/sound/soc/codecs/cs-amp-lib.c b/sound/soc/codecs/cs-amp-lib.c index f9d5c4adf3f2..f9f79da3a9ea 100644 --- a/sound/soc/codecs/cs-amp-lib.c +++ b/sound/soc/codecs/cs-amp-lib.c @@ -541,6 +541,7 @@ EXPORT_SYMBOL_NS_GPL(cs_amp_create_debugfs, "SND_SOC_CS= _AMP_LIB"); static const struct cs_amp_test_hooks cs_amp_test_hook_ptrs =3D { .get_efi_variable =3D cs_amp_get_efi_variable, .write_cal_coeff =3D cs_amp_write_cal_coeff, + .read_cal_coeff =3D cs_amp_read_cal_coeff, }; =20 const struct cs_amp_test_hooks * const cs_amp_test_hooks =3D --=20 2.47.3 From nobody Sun Feb 8 07:52:31 2026 Received: from mx0b-001ae601.pphosted.com (mx0a-001ae601.pphosted.com [67.231.149.25]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 828F932C959; Tue, 21 Oct 2025 10:50:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=67.231.149.25 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761043840; cv=fail; b=PIPzGdw0dqvsrzy61M7kd6wei4XUSnnh5NgJsZjrRm8LRZyoQ37M3wecC7i2JVkFdysaXZarkiKQ1DtqZZOOdtJb7abM/3KtC7V3r53Pt2zA8SdUfm/rXmsfsgZWLDnAuHfqXxzBExgICaqQbZX9mlKOtKb6/YbRM7nj/u7TSTE= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761043840; c=relaxed/simple; bh=IioPaLA4Pv5PWU+RDIN7pzpXTNVkSTRTfJ1O58qAjNY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=A1LWGPmzmxj/d/rsWVPmOW7SJG6R1k6Lf+QCzJwuwzoU/UIE7vTb0fJD/Yw6nMUR+04Pd/zrP2Lxj7onn8ZP9z+0JCQcBAeoBWpYoSkaBcfk1g9ISAOvAFuS3m/XvTOXojru53jqk3xl7GF3RtdAv4DqzXLLn67dBCVMKqLm5Ow= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=opensource.cirrus.com; spf=pass smtp.mailfrom=opensource.cirrus.com; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b=TWm75BGz; dkim=pass (1024-bit key) header.d=cirrus4.onmicrosoft.com header.i=@cirrus4.onmicrosoft.com header.b=Ov+hRTLe; arc=fail smtp.client-ip=67.231.149.25 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=opensource.cirrus.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=opensource.cirrus.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="TWm75BGz"; dkim=pass (1024-bit key) header.d=cirrus4.onmicrosoft.com header.i=@cirrus4.onmicrosoft.com header.b="Ov+hRTLe" Received: from pps.filterd (m0077473.ppops.net [127.0.0.1]) by mx0a-001ae601.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 59KEAbcC3744837; Tue, 21 Oct 2025 05:50:33 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s= PODMain02222019; bh=bn82dMdAFFniYAsIpMMlhGemyy4oDmLfJln1+aQEmPU=; b= TWm75BGzOzDEiL8qkq1uKbbaMJ7Kj7T+nemTP+4i8hInLzkE+X2xd0qi9QuDA0/f MtLiSImdjEE2GhL0ZvKSP00bd0C2/zYdLHCE8jKeq6AnQECJUHrmaG590vkCMHj9 NcA/X4XCBZawcDfhtHtZrw4ckAtxCK6YxQGqf0LHjTHDcf0N24XhokD0Rf9Uc0YF HY//Gg7YSdq5xTf4ecRUGvO2phczz8f0B5izB7K4ctZljDkE3jLzc5QK1LMtaQwz irz1ZF8Rq2Plel5ZA+/7XIPBxCW5D5ktNl6BEjq8uSRTb/xgE9apLhI6FExkrYZF hpyywfwa+aWpEn+l9fXWvQ== Received: from ch4pr04cu002.outbound.protection.outlook.com (mail-northcentralusazon11023129.outbound.protection.outlook.com [40.107.201.129]) by mx0a-001ae601.pphosted.com (PPS) with ESMTPS id 49wnc4sdqn-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Tue, 21 Oct 2025 05:50:33 -0500 (CDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=RMM0AMT/1VE3Xx9atiDutOuHlynhdI/yA7e9nRF5mTycFKPKeiZEMk8gyKK59e6slZ4GduPN2E4QdZmGbfbC47JN+l3sFMD4snq5nmFC44J8/wnPIf1jTqOBfUMffBVsoIigtNZvRdUYhd7FVx06nZWhSSbbrwm1ya6zcgps3AdACuHFWQRphOzZO/+j1E//7ZgGh7aL7I7NG+lRNKARY/5Vc/f/S2E/VRkmBZb70B7rtheMdkAQ0VW5iVpRXPaF9pvySFkIikrgqWS9pKeVpc+BReyNiTk/owZSjrdNOzCyzbB3cYQ4Ms7zuUP1je5xdDtoD+Gk5nIHh/i+Jj1yLQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=bn82dMdAFFniYAsIpMMlhGemyy4oDmLfJln1+aQEmPU=; b=Lup9JtAhMy0r3qjGVRxb7gA0Vc334WEG/75Z76lYtlglZzGcl2w+allTzNu/tl93u9jhhhWspGw9iG4u+VgIkkYazqcMiHZelYAMUw5lEaSI+T9UYq3GSbmS22eq74ovEBwUxqofEHhuvLLbYnzxVFOAqDKYNSkcJovVhTJGtWAqYjwfVzE0uyqxodhV8JIaCJktvbUYE+4yfZqo4gNJK6p2vwQMIJ3iUxdpLh8VrjMVdctpYhbYs79BShO+DaXT4Y/dD29wsKECGOPiZpeGJCX6g6E35m/OSr2GOtNAbHPQje9LIyWWXIR+gFr3xLcSqIFsllC2RCdXmoInryG8tg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=fail (sender ip is 84.19.233.75) smtp.rcpttodomain=cirrus.com smtp.mailfrom=opensource.cirrus.com; dmarc=fail (p=reject sp=reject pct=100) action=oreject header.from=opensource.cirrus.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus4.onmicrosoft.com; s=selector2-cirrus4-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=bn82dMdAFFniYAsIpMMlhGemyy4oDmLfJln1+aQEmPU=; b=Ov+hRTLe37YY6dP1TPNb6WOD8dYaGn43s56QXCnwcJpN2AuYPZCDqRo09ksN7BZvjdHeJuekeSxh0QVcQyN1BSalhk5QB7Ljq0xznVDDPys2KJljjS+SwfpwZtbgy49gxolznBwDodNkvZnsfeY74oRvK9StJRgkyNc6GZ89vcM= Received: from MN2PR08CA0011.namprd08.prod.outlook.com (2603:10b6:208:239::16) by CH3PR19MB8261.namprd19.prod.outlook.com (2603:10b6:610:195::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9228.17; Tue, 21 Oct 2025 10:50:28 +0000 Received: from BL02EPF0001A0FB.namprd03.prod.outlook.com (2603:10b6:208:239:cafe::e6) by MN2PR08CA0011.outlook.office365.com (2603:10b6:208:239::16) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9228.16 via Frontend Transport; Tue, 21 Oct 2025 10:50:27 +0000 X-MS-Exchange-Authentication-Results: spf=fail (sender IP is 84.19.233.75) smtp.mailfrom=opensource.cirrus.com; dkim=none (message not signed) header.d=none;dmarc=fail action=oreject header.from=opensource.cirrus.com; Received-SPF: Fail (protection.outlook.com: domain of opensource.cirrus.com does not designate 84.19.233.75 as permitted sender) receiver=protection.outlook.com; client-ip=84.19.233.75; helo=edirelay1.ad.cirrus.com; Received: from edirelay1.ad.cirrus.com (84.19.233.75) by BL02EPF0001A0FB.mail.protection.outlook.com (10.167.242.102) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9253.7 via Frontend Transport; Tue, 21 Oct 2025 10:50:26 +0000 Received: from ediswmail9.ad.cirrus.com (ediswmail9.ad.cirrus.com [198.61.86.93]) by edirelay1.ad.cirrus.com (Postfix) with ESMTPS id B61FB40655D; Tue, 21 Oct 2025 10:50:22 +0000 (UTC) Received: from ediswws06.ad.cirrus.com (ediswws06.ad.cirrus.com [198.90.208.24]) by ediswmail9.ad.cirrus.com (Postfix) with ESMTPSA id 7FE74822546; Tue, 21 Oct 2025 10:50:22 +0000 (UTC) From: Richard Fitzgerald To: broonie@kernel.org, tiwai@suse.com Cc: linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org, patches@opensource.cirrus.com Subject: [PATCH v2 07/11] ASoC: cs-amp-lib: Return attributes from cs_amp_get_efi_variable() Date: Tue, 21 Oct 2025 11:50:18 +0100 Message-ID: <20251021105022.1013685-8-rf@opensource.cirrus.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251021105022.1013685-1-rf@opensource.cirrus.com> References: <20251021105022.1013685-1-rf@opensource.cirrus.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BL02EPF0001A0FB:EE_|CH3PR19MB8261:EE_ X-MS-Office365-Filtering-Correlation-Id: e23d9a94-405b-442e-a1bb-08de108fa4ee X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|82310400026|376014|36860700013|61400799027; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?gTVV+7gxaq7PA4mMPg5VtrifjPr6ik+urYLnXXt4u1kC0+/twaRgyn5xaHKa?= =?us-ascii?Q?3LCB9/i3MddSYAvo25n+iau6DraL0psSkOxtCgxOiwZJ9q+ZWdhr/TXo5B/H?= =?us-ascii?Q?yQCCUmauXOzWUlfSznQIySbfNkX5RwRQZLv8s9hzJ08EnlOBeOY0Dk9S7htT?= =?us-ascii?Q?NSegk/gUCOfii36M3ncNDihtJVvmWAWeFJ4n2oTOWqTkgsiQymPQrjJF/L+s?= =?us-ascii?Q?jVl7ykWd2d63lIr6UEhENWhTNaOShzIJAz1zJsSJvW6yjtHFxi3e/ett5ird?= =?us-ascii?Q?7liCkJCSTbG/hvzfsTK8pEw2eaI8Mr0dIGmjWYdXwLQPeljgQ7moM/5/GDo7?= =?us-ascii?Q?tSh40tAfNvMmc5xB02/0GVSe3iCvPgliyRD9Jy2ImvppqfZ5BvYuNQYIiWBA?= =?us-ascii?Q?zyMcd5KZPzxHMimahEXTUxb++K8s6BsvjfMNfc1Jm6+dD/NR7oUNIxBTsqxO?= =?us-ascii?Q?VA0pqIB2/gRna3WfQlE3q2fI5qPxX3+3ollWeIIz62BgvfvZhr46+j+onMoe?= =?us-ascii?Q?5k+/AACtlDXGTlHXBzPWdEm9rnY22v3JmyKLYZjFHFqiV++VsUXKTknIlxAD?= =?us-ascii?Q?n86hLc0/TixhSO7TGblyeCUJxVvfoi6bCttymAUCuBiW7BEfLVrbeVSLpQ38?= =?us-ascii?Q?0eT30t3zmlraTb63ZPdThc6nOPDR2wfTT/N3+fueJw4UbGJqAGzUtoLmZZ+y?= =?us-ascii?Q?yB76+fylvDLgvp+piwi863Z7I3AR/mIx8s5cff2hnOHI1Du0P2AZ3hw1O3nP?= =?us-ascii?Q?KNOfmV/Mwhha0OuI2g6IFYmSgUhsHyeYez00KOJ8bZ3/gUJCBksPRHo9VITd?= =?us-ascii?Q?4ZBrlJxOizHIaND9TfW9mOBmd4t7sNkM/aSCL2Xy+YHWzzphb4bSCoqFJNvH?= =?us-ascii?Q?DtM3VF+td1Iu7vjiNfADUgPQtvHku0aufhp2kwxQCzHQ86CquHHBK7shfSLZ?= =?us-ascii?Q?m9FaUSHVXY11OqHs2CKoqvRCB9x4ihZKykaMCixRCUEABISPRP+TczdntzWV?= =?us-ascii?Q?fo1HFyXAc3dLLZn2s1udSVwBx3tPLh9x42IShFIYSCBh09wiA43w7h3K3NqL?= =?us-ascii?Q?hdfzQADqA+ziGZogZk0JXwZt7VL3VmDDpgwiX1hrc1YkS1C1qDkRlUs0AXeR?= =?us-ascii?Q?2AAYYpwH+AeePrdSR6OOPVxteqQLCJ0SPKamEN8q+PDMWwyubI0grsUr+tLc?= =?us-ascii?Q?ruP+4mWTMHY1G1HUVcFvKgrFJ335hmMHcVuEYol1xrsJL8VQdFaDIH8wWqeh?= =?us-ascii?Q?W5rfBb1mAwr8OYCFu5xJ5vmT3wg22bjpVhKF3+2Of+55QXi99V/p4+bBECts?= =?us-ascii?Q?BNTTX6eGDr/WMyruHaV/pjgRH+BIVdKCgHkW8RK68h4VO0xAMEi2saUsQO/w?= =?us-ascii?Q?vYq/d737N65XyVXgxEWvSwoMepAnx0RdiQQLWdDHbb5fOjIFAXOsyXnwMsiR?= =?us-ascii?Q?zlXhR+1oWyPFn36BG7rMph3HHx3iYVC0Q6YzcOG4HDvYHFnE0bk4E6CVkmen?= =?us-ascii?Q?WDEYLo2v3hFjJJGH2NTYzmFpd65vbCBo3rn/8wvBZR3ViFVXlrx3e8/nlTwB?= =?us-ascii?Q?7ugzrCdtdIcf0nhibL0=3D?= X-Forefront-Antispam-Report: CIP:84.19.233.75;CTRY:GB;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:edirelay1.ad.cirrus.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(82310400026)(376014)(36860700013)(61400799027);DIR:OUT;SFP:1102; X-OriginatorOrg: opensource.cirrus.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Oct 2025 10:50:26.4603 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: e23d9a94-405b-442e-a1bb-08de108fa4ee X-MS-Exchange-CrossTenant-Id: bec09025-e5bc-40d1-a355-8e955c307de8 X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=bec09025-e5bc-40d1-a355-8e955c307de8;Ip=[84.19.233.75];Helo=[edirelay1.ad.cirrus.com] X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: TreatMessagesAsInternal-BL02EPF0001A0FB.namprd03.prod.outlook.com X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CH3PR19MB8261 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMDIxMDA4NSBTYWx0ZWRfX6Tgj8bbIZ+1Q fjnalToCKXdeZVqn5MqzqEGq6X1v24okVsjja943hNgAdI4Wf/ZZpU+qika5MhqilifppVNX/P3 Hl+NTq7uRqvo0Mxqy9DY9KtBWk7wL8gG/KQ2SWJ7Bte5xk2BgB4YD+c4Kma7nsMU+xTpZF84Xvx LvmeNKn22m+M2JKRpNuMl+3YIK2Lu7Gz/A+iUMuydHsXIdZv7PKCNxKy7iFUUjSsxqOzn9Uc2pL JGrnc9wP5mLMnC+Eq0S1J9Yz5wXUFUw3SzXDbdYDXAO69Sc3uUxhfYDXkwwhpYS7bWYHoMgv+z5 LZa7+KsPSm9RWwP/TykZsggM8cXRDIlPTQi+zWLnAQoRxtadDRTyI7u0DSuQrL59UrWtm2rHRtA +KXXhsrDJkcVgnhyFM5Gy0gIZoyUnw== X-Proofpoint-GUID: 72iG1hYbn0TqaXQOOEFftvEf_4IrmDXb X-Proofpoint-ORIG-GUID: 72iG1hYbn0TqaXQOOEFftvEf_4IrmDXb X-Authority-Analysis: v=2.4 cv=bf1mkePB c=1 sm=1 tr=0 ts=68f76579 cx=c_pps a=roYWoV4TocsuA6t8t8h9Ow==:117 a=h1hSm8JtM9GN1ddwPAif2w==:17 a=6eWqkTHjU83fiwn7nKZWdM+Sl24=:19 a=z/mQ4Ysz8XfWz/Q5cLBRGdckG28=:19 a=x6icFKpwvdMA:10 a=s63m1ICgrNkA:10 a=RWc_ulEos4gA:10 a=VkNPw1HP01LnGYTKEx00:22 a=w1d2syhTAAAA:8 a=BfivipjO2gqBdDjawAAA:9 X-Proofpoint-Spam-Reason: safe Content-Type: text/plain; charset="utf-8" Add a pointer argument to cs_amp_get_efi_variable() to optionally return the EFI variable attributes. Originally this function internally consumed the attributes from efi.get_variable(). The calling code did not use the attributes so this was a small simplification. However, when writing to a pre-existing variable we would want to pass the existing attributes to efi.set_variable(). This patch deals with the change to return the attribute in preparation for adding code to update the variable. Signed-off-by: Richard Fitzgerald Reviewed-by: Takashi Iwai --- No changes since V1. include/sound/cs-amp-lib.h | 1 + sound/soc/codecs/cs-amp-lib-test.c | 23 +++++++++++++++++++++++ sound/soc/codecs/cs-amp-lib.c | 15 ++++++++++----- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/include/sound/cs-amp-lib.h b/include/sound/cs-amp-lib.h index efa744133a35..2e5616a5e1f7 100644 --- a/include/sound/cs-amp-lib.h +++ b/include/sound/cs-amp-lib.h @@ -66,6 +66,7 @@ static inline u64 cs_amp_cal_target_u64(const struct cirr= us_amp_cal_data *data) struct cs_amp_test_hooks { efi_status_t (*get_efi_variable)(efi_char16_t *name, efi_guid_t *guid, + u32 *returned_attr, unsigned long *size, void *buf); =20 diff --git a/sound/soc/codecs/cs-amp-lib-test.c b/sound/soc/codecs/cs-amp-l= ib-test.c index 6878941a8f57..b00ba65badd5 100644 --- a/sound/soc/codecs/cs-amp-lib-test.c +++ b/sound/soc/codecs/cs-amp-lib-test.c @@ -89,6 +89,7 @@ static u64 cs_amp_lib_test_get_target_uid(struct kunit *t= est) /* Redirected get_efi_variable to simulate that the file is too short */ static efi_status_t cs_amp_lib_test_get_efi_variable_nohead(efi_char16_t *= name, efi_guid_t *guid, + u32 *returned_attr, unsigned long *size, void *buf) { @@ -121,6 +122,7 @@ static void cs_amp_lib_test_cal_data_too_short_test(str= uct kunit *test) /* Redirected get_efi_variable to simulate that the count is larger than t= he file */ static efi_status_t cs_amp_lib_test_get_efi_variable_bad_count(efi_char16_= t *name, efi_guid_t *guid, + u32 *returned_attr, unsigned long *size, void *buf) { @@ -164,6 +166,7 @@ static void cs_amp_lib_test_cal_count_too_big_test(stru= ct kunit *test) /* Redirected get_efi_variable to simulate that the variable not found */ static efi_status_t cs_amp_lib_test_get_efi_variable_none(efi_char16_t *na= me, efi_guid_t *guid, + u32 *returned_attr, unsigned long *size, void *buf) { @@ -191,6 +194,7 @@ static void cs_amp_lib_test_no_cal_data_test(struct kun= it *test) /* Redirected get_efi_variable to simulate reading a cal data blob */ static efi_status_t cs_amp_lib_test_get_efi_variable(efi_char16_t *name, efi_guid_t *guid, + u32 *returned_attr, unsigned long *size, void *buf) { @@ -217,11 +221,18 @@ static efi_status_t cs_amp_lib_test_get_efi_variable(= efi_char16_t *name, =20 memcpy(buf, priv->cal_blob, priv->cal_blob->size); =20 + if (returned_attr) { + *returned_attr =3D EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS; + } + return EFI_SUCCESS; } =20 static efi_status_t cs_amp_lib_test_get_hp_cal_efi_variable(efi_char16_t *= name, efi_guid_t *guid, + u32 *returned_attr, unsigned long *size, void *buf) { @@ -248,6 +259,12 @@ static efi_status_t cs_amp_lib_test_get_hp_cal_efi_var= iable(efi_char16_t *name, =20 memcpy(buf, priv->cal_blob, priv->cal_blob->size); =20 + if (returned_attr) { + *returned_attr =3D EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS; + } + return EFI_SUCCESS; } =20 @@ -786,6 +803,7 @@ static void cs_amp_lib_test_spkid_lenovo_not_present(st= ruct kunit *test) =20 static efi_status_t cs_amp_lib_test_get_efi_variable_lenovo_d0(efi_char16_= t *name, efi_guid_t *guid, + u32 *returned_attr, unsigned long *size, void *buf) { @@ -804,6 +822,7 @@ static efi_status_t cs_amp_lib_test_get_efi_variable_le= novo_d0(efi_char16_t *nam =20 static efi_status_t cs_amp_lib_test_get_efi_variable_lenovo_d1(efi_char16_= t *name, efi_guid_t *guid, + u32 *returned_attr, unsigned long *size, void *buf) { @@ -822,6 +841,7 @@ static efi_status_t cs_amp_lib_test_get_efi_variable_le= novo_d1(efi_char16_t *nam =20 static efi_status_t cs_amp_lib_test_get_efi_variable_lenovo_00(efi_char16_= t *name, efi_guid_t *guid, + u32 *returned_attr, unsigned long *size, void *buf) { @@ -873,6 +893,7 @@ static void cs_amp_lib_test_spkid_lenovo_illegal(struct= kunit *test) =20 static efi_status_t cs_amp_lib_test_get_efi_variable_buf_too_small(efi_cha= r16_t *name, efi_guid_t *guid, + u32 *returned_attr, unsigned long *size, void *buf) { @@ -893,6 +914,7 @@ static void cs_amp_lib_test_spkid_lenovo_oversize(struc= t kunit *test) =20 static efi_status_t cs_amp_lib_test_get_efi_variable_hp_30(efi_char16_t *n= ame, efi_guid_t *guid, + u32 *returned_attr, unsigned long *size, void *buf) { @@ -911,6 +933,7 @@ static efi_status_t cs_amp_lib_test_get_efi_variable_hp= _30(efi_char16_t *name, =20 static efi_status_t cs_amp_lib_test_get_efi_variable_hp_31(efi_char16_t *n= ame, efi_guid_t *guid, + u32 *returned_attr, unsigned long *size, void *buf) { diff --git a/sound/soc/codecs/cs-amp-lib.c b/sound/soc/codecs/cs-amp-lib.c index f9f79da3a9ea..c5791cbeb5b8 100644 --- a/sound/soc/codecs/cs-amp-lib.c +++ b/sound/soc/codecs/cs-amp-lib.c @@ -245,15 +245,20 @@ EXPORT_SYMBOL_NS_GPL(cs_amp_write_ambient_temp, "SND_= SOC_CS_AMP_LIB"); =20 static efi_status_t cs_amp_get_efi_variable(efi_char16_t *name, efi_guid_t *guid, + u32 *returned_attr, unsigned long *size, void *buf) { u32 attr; =20 - KUNIT_STATIC_STUB_REDIRECT(cs_amp_get_efi_variable, name, guid, size, buf= ); + if (!returned_attr) + returned_attr =3D &attr; + + KUNIT_STATIC_STUB_REDIRECT(cs_amp_get_efi_variable, name, guid, + returned_attr, size, buf); =20 if (efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE)) - return efi.get_variable(name, guid, &attr, size, buf); + return efi.get_variable(name, guid, returned_attr, size, buf); =20 return EFI_NOT_FOUND; } @@ -288,7 +293,7 @@ static struct cirrus_amp_efi_data *cs_amp_get_cal_efi_b= uffer(struct device *dev) for (i =3D 0; i < ARRAY_SIZE(cs_amp_lib_cal_efivars); i++) { status =3D cs_amp_get_efi_variable(cs_amp_lib_cal_efivars[i].name, cs_amp_lib_cal_efivars[i].guid, - &data_size, NULL); + NULL, &data_size, NULL); if (status =3D=3D EFI_BUFFER_TOO_SMALL) break; } @@ -308,7 +313,7 @@ static struct cirrus_amp_efi_data *cs_amp_get_cal_efi_b= uffer(struct device *dev) =20 status =3D cs_amp_get_efi_variable(cs_amp_lib_cal_efivars[i].name, cs_amp_lib_cal_efivars[i].guid, - &data_size, data); + NULL, &data_size, data); if (status !=3D EFI_SUCCESS) { ret =3D -EINVAL; goto err; @@ -452,7 +457,7 @@ static int cs_amp_get_efi_byte_spkid(struct device *dev= , const struct cs_amp_spk int i, ret; =20 size =3D sizeof(spkid); - status =3D cs_amp_get_efi_variable(info->name, info->guid, &size, &spkid); + status =3D cs_amp_get_efi_variable(info->name, info->guid, NULL, &size, &= spkid); ret =3D cs_amp_convert_efi_status(status); if (ret < 0) return ret; --=20 2.47.3 From nobody Sun Feb 8 07:52:31 2026 Received: from mx0b-001ae601.pphosted.com (mx0a-001ae601.pphosted.com [67.231.149.25]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 45FFF32C950; Tue, 21 Oct 2025 10:50:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=67.231.149.25 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761043840; cv=fail; b=W492z52d44ms9xDtLkBj4v1N7w/KhH5/zEpNMnNhjtDymD0YzbghJng3w0Jok4kDip7sPzfVDqVuFiRA0OUr4xpDb2fzB6ri/AUeywZzHhW2d+V4SzsvnvZPNXHSUpSTXr123L70P7zkD9sDuOWRQJ5xL2cGQusq2fddJHQ76LE= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761043840; c=relaxed/simple; bh=xLtGK1ivnuGtGJMqjkyMmtih5PihEDtqHLoxtEbWDlk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=cP2BnLqDf3mPSfiv3VCU7tPJQDK5Sv5HcDyEQxLA2HNFull5jRpO0xVNvygWYR2cqi7ymILr4y8UinyjVBp3hh1RQOnkdXfrZaVry5dwdBazcnM4eXJUi9oaEKsBZREIgdTKdCX4gi9yTBlSLJUkcFTyL2sBP1XmykXZQS68qOQ= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=opensource.cirrus.com; spf=pass smtp.mailfrom=opensource.cirrus.com; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b=S/7f1kTG; dkim=pass (1024-bit key) header.d=cirrus4.onmicrosoft.com header.i=@cirrus4.onmicrosoft.com header.b=H4KIl4kh; arc=fail smtp.client-ip=67.231.149.25 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=opensource.cirrus.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=opensource.cirrus.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="S/7f1kTG"; dkim=pass (1024-bit key) header.d=cirrus4.onmicrosoft.com header.i=@cirrus4.onmicrosoft.com header.b="H4KIl4kh" Received: from pps.filterd (m0077473.ppops.net [127.0.0.1]) by mx0a-001ae601.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 59L4jHCu952328; Tue, 21 Oct 2025 05:50:32 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s= PODMain02222019; bh=Ofqk3bxwqLVED1T0uwjL73JBlUwVV1bngeH9WqD8nro=; b= S/7f1kTGNEyNbpth6Y1aQB9EsQHJit/40JExM5QkVaXc8q0qM5SFjIrNE/Otkrzk 1FjB4isCficQiAp2vcah+JLU6rMzkakTYPEQM3QG0HZp/SWodyw+oESMinwPnIwu nluoPh7HbpI28N5FSrzMNBVN79GTTyhrsvk56nv/7waMyskMLzTinU20dmIPWXvu yXJcknH9uFWAvyg+xOinhR/z17kkoUMNMzzgoxwLiSioegw3aMiSbIJI/8hYhxJk fNI7NOnhE0GP26AxF1jBARP7NlTy1IeexKWx6kETNCxAoKpbIYPGERW1Gc2TcoaN Jvt5T2npktro7UylhlCedA== Received: from bn8pr05cu002.outbound.protection.outlook.com (mail-eastus2azon11021085.outbound.protection.outlook.com [52.101.57.85]) by mx0a-001ae601.pphosted.com (PPS) with ESMTPS id 49wnc4sdqm-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Tue, 21 Oct 2025 05:50:32 -0500 (CDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=UrCL7NVnzZmfOJd6vfJMclKyW3Lfko5W07ZCiMLPO9UHF3mqarspfMmU+v+mOQj7i45jmIrrlBTDmb7UYblmh5Fuis4+XiatjSJka0tEyy0/BTGs8k/tPfV1HkZIhQlGTUtPXGeAot9SHcT/LU7sBIXzOtEcT3mENqPxNG2tDM6OHZjXwj2kEA+46zrBXIRq4/1M9fRYgIRz47IMY4D2IBgK+GnEHHKFXlSy5QGxPUzCnWYFLYvsGIue8lIMuVVgs+CPNvBmgABxZHyw18Y+A7pgHWibahG5Y5VDfro+qCE0sbrlewCFV0VYZJXbisq6kxxV6/ichVMgoss89yx+sA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=Ofqk3bxwqLVED1T0uwjL73JBlUwVV1bngeH9WqD8nro=; b=exw658PVtbeEzSTK6H2Rk4vnaLyffnWcUjvKRzXudWjgknNGz1UGPjKhF3vnBOME8SUJkkGE5I//yIS8yoVptVCdzf/KgV1ZV7WgUlLNmMWvjpM22L4hgaPaBVlEr+CU7K0y+upoTfyBjLLq9xkRH0UARCNjOtkMiQF1d8JlWPqiyvJ4+scbkAN9pKqU5hNrZ3u1XK/0B6AmZwHGpG5YsICfqlDpfAQnnE6JRUjcMvigWiH1L6f59nfStcN4i5efAFNAAl2oY7c5YNg3R/ZB+RVcKptSkjciSObPafAzg/+3BB2/K/rrb4MVXBgNZ39zqmuqyDMWLBnnta+Japbmyg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=fail (sender ip is 84.19.233.75) smtp.rcpttodomain=cirrus.com smtp.mailfrom=opensource.cirrus.com; dmarc=fail (p=reject sp=reject pct=100) action=oreject header.from=opensource.cirrus.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus4.onmicrosoft.com; s=selector2-cirrus4-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=Ofqk3bxwqLVED1T0uwjL73JBlUwVV1bngeH9WqD8nro=; b=H4KIl4khD+uRvQ5WVUUJhwqLg8PDnBfv6pQGTFmnfId/ED5vwqZYNz2c9sIXUC4TrMqklTv6FrbMLIqt+IfisOqRQNg1mbRQzQlQPVp1rl3Hibr5qYjlYF3M45ASJfqwxLbNG488bTeYvWHzY3ibdCHXqWzH3cS+88oCDCBiZB8= Received: from SN7P220CA0010.NAMP220.PROD.OUTLOOK.COM (2603:10b6:806:123::15) by IA3PR19MB8544.namprd19.prod.outlook.com (2603:10b6:208:518::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9253.12; Tue, 21 Oct 2025 10:50:27 +0000 Received: from SA2PEPF000015CD.namprd03.prod.outlook.com (2603:10b6:806:123:cafe::8f) by SN7P220CA0010.outlook.office365.com (2603:10b6:806:123::15) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9228.17 via Frontend Transport; Tue, 21 Oct 2025 10:50:27 +0000 X-MS-Exchange-Authentication-Results: spf=fail (sender IP is 84.19.233.75) smtp.mailfrom=opensource.cirrus.com; dkim=none (message not signed) header.d=none;dmarc=fail action=oreject header.from=opensource.cirrus.com; Received-SPF: Fail (protection.outlook.com: domain of opensource.cirrus.com does not designate 84.19.233.75 as permitted sender) receiver=protection.outlook.com; client-ip=84.19.233.75; helo=edirelay1.ad.cirrus.com; Received: from edirelay1.ad.cirrus.com (84.19.233.75) by SA2PEPF000015CD.mail.protection.outlook.com (10.167.241.203) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9253.7 via Frontend Transport; Tue, 21 Oct 2025 10:50:26 +0000 Received: from ediswmail9.ad.cirrus.com (ediswmail9.ad.cirrus.com [198.61.86.93]) by edirelay1.ad.cirrus.com (Postfix) with ESMTPS id BABE2406565; Tue, 21 Oct 2025 10:50:22 +0000 (UTC) Received: from ediswws06.ad.cirrus.com (ediswws06.ad.cirrus.com [198.90.208.24]) by ediswmail9.ad.cirrus.com (Postfix) with ESMTPSA id 857F4822547; Tue, 21 Oct 2025 10:50:22 +0000 (UTC) From: Richard Fitzgerald To: broonie@kernel.org, tiwai@suse.com Cc: linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org, patches@opensource.cirrus.com Subject: [PATCH v2 08/11] ASoC: cs-amp-lib: Add function to write calibration to UEFI Date: Tue, 21 Oct 2025 11:50:19 +0100 Message-ID: <20251021105022.1013685-9-rf@opensource.cirrus.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251021105022.1013685-1-rf@opensource.cirrus.com> References: <20251021105022.1013685-1-rf@opensource.cirrus.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SA2PEPF000015CD:EE_|IA3PR19MB8544:EE_ X-MS-Office365-Filtering-Correlation-Id: f494abb9-c768-4758-0100-08de108fa507 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|82310400026|61400799027|36860700013; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?Ozft1th67Ctv5JhAZfHsGhBQpO4FNKBRlzdVm0pwKjVgv5U+5XsFZ+bQaqne?= =?us-ascii?Q?EyekFeEryA8qHtp0Ltze3AwZfeHt5WPH/hkutOPkIEPzMNKRG47ZDMJVYu+g?= =?us-ascii?Q?LevHxO+lIEhKJRRflKr0v52C4M3FptLlZhF1tLfaCy8RjUlXZn0O9rsfZLUa?= =?us-ascii?Q?y+8LewB2avM+f92HufyFy4bgy7ziEJzMf76tS9SsG91NtWum1hJW8wlW8Zjp?= =?us-ascii?Q?QJWrpk+OnFd+InoTKD6crkx/JDWsV8/kYYiFkhExrjq75cRb3YEwYEh0DGn1?= =?us-ascii?Q?gAR0TZrInRbgJLa/mpy1TyGCrW2vGFivgzFnLSUK4HvcTNAU0Jm18AgNUXps?= =?us-ascii?Q?AajszYR0VBXi7i8NGPzI6ueM97qsm6y+2+p5+qTZNpMIfGIn5nVLjGE9pyu0?= =?us-ascii?Q?ahgICtSW6Nq5r+iSzTJMo4rvgDckI5sCVXOsbLJ9onUQ1pZgslHG9atStI5A?= =?us-ascii?Q?ve60rbIkUE+EqLYpoUk0rif1zb/Qi0UtHs1sIc8QF5tW60/F3Tc2PF866/mB?= =?us-ascii?Q?s/03iEci1DDRUzq5EARPqJjm9tXOO2dBWqlClj4TTw5W43xArJV8HievM0o5?= =?us-ascii?Q?paFOAerrUrRknixhzVfkF2IuK7mM4QtmWTft6gMyxVlchObqUKBdGDJ55ZrQ?= =?us-ascii?Q?ay8yJ59mbOYhTA8o3CGXSYZaKDxh3osJ0HRhdNXUntt4ESwiNsBeiEmEhnfk?= =?us-ascii?Q?BnH4rZefAvGFFcssqopo91u17qxIFbuWwCxZ2szk6+dZIt5tv1qCqjboMMdG?= =?us-ascii?Q?hDQMzdKKWBV9ZY6MtS7s8/5m634yqZPszW4glsY5S+a0QZ7l9X3NnEgK9pLS?= =?us-ascii?Q?HOFFvYw4Q48TmIMoEbFuD5hzFzZ0uGGBpMxA50943kCmQIj5TRLVWCfFtmSH?= =?us-ascii?Q?mDoi3QrL/ZO+vAlnKv+oVxB3coALvv3IbWahh6us+Qf6EIH/wW+MRIzMRP9v?= =?us-ascii?Q?xDYXP7kohcII7FBvcbVNxpAA0nscW5ILExsBMPEucfj0+467STlcX1wtxdsg?= =?us-ascii?Q?4ExQybTeteZQ8q89f2p0hD/uFAeL6ZcrX7EYQcidLMMIcmaZA+MV7w53Azql?= =?us-ascii?Q?JOxY1vB3BWluYrlApvjhCqyLP8zpHzc+jFNGPn2g7gQC3lkcqKIr3MyM2iCG?= =?us-ascii?Q?QNnQMlSjmFh+RAp1qJUcmhqfgQi0uqty8ASpblmQKvlLjLs1x2EihnqlLmbQ?= =?us-ascii?Q?bVI3+ma97FEyAaTQMA1QAOk9Agz55jwujzJdfooHm3pL2GfXrELTIvQB6X1H?= =?us-ascii?Q?kgmIjpOTxd9kRJJhio+rN6kcu8erlhbV9HCkzkvsg7thAD2yAdKsoqRf4dVI?= =?us-ascii?Q?ADpG4/dFlwUZoIrV6malL8bCBJzJx+OiN1wyVwINTbU8dc9K+RkDO1AgcCnp?= =?us-ascii?Q?/KMip2pD8ioTsKjL1KrCEX5aUPjhIGYQ1TRlXXkIULNWlB6IcZPButjUJACO?= =?us-ascii?Q?6jypSBT9ntQdb2/VN8tigCpyG5F+WjxkoFHvHWj4CKkszknyRnCHbsJLrDdO?= =?us-ascii?Q?lHtXsRtmp51f/MK+DRBlaioKAppI0hwShoHfAGuHVoidaCUNcy9ZvLL1G0RZ?= =?us-ascii?Q?z5RCENK2B8Ma+Cu9yX4=3D?= X-Forefront-Antispam-Report: CIP:84.19.233.75;CTRY:GB;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:edirelay1.ad.cirrus.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(376014)(82310400026)(61400799027)(36860700013);DIR:OUT;SFP:1102; X-OriginatorOrg: opensource.cirrus.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Oct 2025 10:50:26.5541 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: f494abb9-c768-4758-0100-08de108fa507 X-MS-Exchange-CrossTenant-Id: bec09025-e5bc-40d1-a355-8e955c307de8 X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=bec09025-e5bc-40d1-a355-8e955c307de8;Ip=[84.19.233.75];Helo=[edirelay1.ad.cirrus.com] X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: TreatMessagesAsInternal-SA2PEPF000015CD.namprd03.prod.outlook.com X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: IA3PR19MB8544 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMDIxMDA4NSBTYWx0ZWRfX2xZdb4bPesFY bVLP1L4Ej9uJgEysGAJ7pfBbrwv/m6A+69ZUbyuHUX/KOF5xEEH5uyn1ilZjjF2EUK8tB9u8Ukv jECwna3unszm6YGpSacmTx2SKX8W5LOY/17B44vhVJBAs5YmoSIv2isJqrtYZvSvkCSGfoAw85M jHaiGAkxYlkB4eYNs4Ep0XU2MBTmGPwWxcOrtqJ2DZYI1vOgVOjIsOE+Aj7t+IczI6u5PHE2p4A 6TPWEmSrWcsKElmG6btq5aJzvdw7Fs3NxWXLWN1H4TnXUMbq5iGyXL1vaGTie7cmQmS9H0cdCAM x7X//Z+pDrLgvATOGtRGOEIQPHj9a1GHEPXzmQh7ASEvAons8QYeM1LpP9VgG6nRITIpJ/CstnO j4GoZBbPCWERdVezIq6Z2siIcwMXBw== X-Proofpoint-GUID: VI9FZ8GXaNK3YlXyO4fx5aOc3jgPbog- X-Proofpoint-ORIG-GUID: VI9FZ8GXaNK3YlXyO4fx5aOc3jgPbog- X-Authority-Analysis: v=2.4 cv=bf1mkePB c=1 sm=1 tr=0 ts=68f76578 cx=c_pps a=SDOlI5lSWczX7ANjW/fhbQ==:117 a=h1hSm8JtM9GN1ddwPAif2w==:17 a=6eWqkTHjU83fiwn7nKZWdM+Sl24=:19 a=z/mQ4Ysz8XfWz/Q5cLBRGdckG28=:19 a=x6icFKpwvdMA:10 a=s63m1ICgrNkA:10 a=RWc_ulEos4gA:10 a=VkNPw1HP01LnGYTKEx00:22 a=w1d2syhTAAAA:8 a=Rj8EF44HmWohM5JNfgoA:9 X-Proofpoint-Spam-Reason: safe Content-Type: text/plain; charset="utf-8" Add cs_amp_set_efi_calibration_data() to write an amp calibration blob to UEFI calibration variable. The UEFI variable will be updated or created as necessary. - If a Vendor-specific variable exists it will be updated, else if the Cirrus variable exists it will be update else the Cirrus variable will be created. Some collateral changes are required: - cs_amp_convert_efi_status() now specifically handles EFI_WRITE_PROTECTED error. - cs_amp_get_cal_efi_buffer() can optionally return the name, guid and attr of the variable it found. - cs_amp_get_cal_efi_buffer() will update the 'size' field of the returned data blob if it is zero. The BIOS could have pre-allocated the UEFI variable as zero-filled Signed-off-by: Richard Fitzgerald Reviewed-by: Takashi Iwai --- No changes since V1. include/sound/cs-amp-lib.h | 2 + sound/soc/codecs/cs-amp-lib.c | 190 +++++++++++++++++++++++++++++++++- 2 files changed, 188 insertions(+), 4 deletions(-) diff --git a/include/sound/cs-amp-lib.h b/include/sound/cs-amp-lib.h index 2e5616a5e1f7..240bc53a9307 100644 --- a/include/sound/cs-amp-lib.h +++ b/include/sound/cs-amp-lib.h @@ -55,6 +55,8 @@ int cs_amp_write_ambient_temp(struct cs_dsp *dsp, u32 temp); int cs_amp_get_efi_calibration_data(struct device *dev, u64 target_uid, in= t amp_index, struct cirrus_amp_cal_data *out_data); +int cs_amp_set_efi_calibration_data(struct device *dev, int amp_index, int= num_amps, + const struct cirrus_amp_cal_data *in_data); int cs_amp_get_vendor_spkid(struct device *dev); struct dentry *cs_amp_create_debugfs(struct device *dev); =20 diff --git a/sound/soc/codecs/cs-amp-lib.c b/sound/soc/codecs/cs-amp-lib.c index c5791cbeb5b8..7038574e3f4b 100644 --- a/sound/soc/codecs/cs-amp-lib.c +++ b/sound/soc/codecs/cs-amp-lib.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -49,9 +50,16 @@ static const struct cs_amp_lib_cal_efivar { }, }; =20 +#define CS_AMP_CAL_DEFAULT_EFI_ATTR \ + (EFI_VARIABLE_NON_VOLATILE | \ + EFI_VARIABLE_BOOTSERVICE_ACCESS | \ + EFI_VARIABLE_RUNTIME_ACCESS) + /* Offset from Unix time to Windows time (100ns since 1 Jan 1601) */ #define UNIX_TIME_TO_WINDOWS_TIME_OFFSET 116444736000000000ULL =20 +static DEFINE_MUTEX(cs_amp_efi_cal_write_lock); + static u64 cs_amp_time_now_in_windows_time(void) { u64 time_in_100ns =3D div_u64(ktime_get_real_ns(), 100); @@ -263,6 +271,20 @@ static efi_status_t cs_amp_get_efi_variable(efi_char16= _t *name, return EFI_NOT_FOUND; } =20 +static efi_status_t cs_amp_set_efi_variable(efi_char16_t *name, + efi_guid_t *guid, + u32 attr, + unsigned long size, + void *buf) +{ + KUNIT_STATIC_STUB_REDIRECT(cs_amp_set_efi_variable, name, guid, attr, siz= e, buf); + + if (!efi_rt_services_supported(EFI_RT_SUPPORTED_SET_VARIABLE)) + return EFI_NOT_FOUND; + + return efi.set_variable(name, guid, attr, size, buf); +} + static int cs_amp_convert_efi_status(efi_status_t status) { switch (status) { @@ -272,6 +294,7 @@ static int cs_amp_convert_efi_status(efi_status_t statu= s) return -ENOENT; case EFI_BUFFER_TOO_SMALL: return -EFBIG; + case EFI_WRITE_PROTECTED: case EFI_UNSUPPORTED: case EFI_ACCESS_DENIED: case EFI_SECURITY_VIOLATION: @@ -281,7 +304,10 @@ static int cs_amp_convert_efi_status(efi_status_t stat= us) } } =20 -static struct cirrus_amp_efi_data *cs_amp_get_cal_efi_buffer(struct device= *dev) +static struct cirrus_amp_efi_data *cs_amp_get_cal_efi_buffer(struct device= *dev, + efi_char16_t **name, + efi_guid_t **guid, + u32 *attr) { struct cirrus_amp_efi_data *efi_data; unsigned long data_size =3D 0; @@ -293,7 +319,7 @@ static struct cirrus_amp_efi_data *cs_amp_get_cal_efi_b= uffer(struct device *dev) for (i =3D 0; i < ARRAY_SIZE(cs_amp_lib_cal_efivars); i++) { status =3D cs_amp_get_efi_variable(cs_amp_lib_cal_efivars[i].name, cs_amp_lib_cal_efivars[i].guid, - NULL, &data_size, NULL); + attr, &data_size, NULL); if (status =3D=3D EFI_BUFFER_TOO_SMALL) break; } @@ -301,6 +327,12 @@ static struct cirrus_amp_efi_data *cs_amp_get_cal_efi_= buffer(struct device *dev) if (status !=3D EFI_BUFFER_TOO_SMALL) return ERR_PTR(-ENOENT); =20 + if (name) + *name =3D cs_amp_lib_cal_efivars[i].name; + + if (guid) + *guid =3D cs_amp_lib_cal_efivars[i].guid; + if (data_size < sizeof(*efi_data)) { dev_err(dev, "EFI cal variable truncated\n"); return ERR_PTR(-EOVERFLOW); @@ -313,7 +345,7 @@ static struct cirrus_amp_efi_data *cs_amp_get_cal_efi_b= uffer(struct device *dev) =20 status =3D cs_amp_get_efi_variable(cs_amp_lib_cal_efivars[i].name, cs_amp_lib_cal_efivars[i].guid, - NULL, &data_size, data); + attr, &data_size, data); if (status !=3D EFI_SUCCESS) { ret =3D -EINVAL; goto err; @@ -329,6 +361,10 @@ static struct cirrus_amp_efi_data *cs_amp_get_cal_efi_= buffer(struct device *dev) goto err; } =20 + /* This could be zero-filled space pre-allocated by the BIOS */ + if (efi_data->size =3D=3D 0) + efi_data->size =3D data_size; + return efi_data; =20 err: @@ -338,6 +374,20 @@ static struct cirrus_amp_efi_data *cs_amp_get_cal_efi_= buffer(struct device *dev) return ERR_PTR(ret); } =20 +static int cs_amp_set_cal_efi_buffer(struct device *dev, + efi_char16_t *name, + efi_guid_t *guid, + u32 attr, + struct cirrus_amp_efi_data *data) +{ + efi_status_t status; + + status =3D cs_amp_set_efi_variable(name, guid, attr, + struct_size(data, data, data->count), data); + + return cs_amp_convert_efi_status(status); +} + static int _cs_amp_get_efi_calibration_data(struct device *dev, u64 target= _uid, int amp_index, struct cirrus_amp_cal_data *out_data) { @@ -345,7 +395,7 @@ static int _cs_amp_get_efi_calibration_data(struct devi= ce *dev, u64 target_uid, struct cirrus_amp_cal_data *cal =3D NULL; int i, ret; =20 - efi_data =3D cs_amp_get_cal_efi_buffer(dev); + efi_data =3D cs_amp_get_cal_efi_buffer(dev, NULL, NULL, NULL); if (IS_ERR(efi_data)) return PTR_ERR(efi_data); =20 @@ -397,6 +447,98 @@ static int _cs_amp_get_efi_calibration_data(struct dev= ice *dev, u64 target_uid, return ret; } =20 +static int _cs_amp_set_efi_calibration_data(struct device *dev, int amp_in= dex, int num_amps, + const struct cirrus_amp_cal_data *in_data) +{ + u64 cal_target =3D cs_amp_cal_target_u64(in_data); + unsigned long num_entries; + struct cirrus_amp_efi_data *data __free(kfree) =3D NULL; + efi_char16_t *name =3D CIRRUS_LOGIC_CALIBRATION_EFI_NAME; + efi_guid_t *guid =3D &CIRRUS_LOGIC_CALIBRATION_EFI_GUID; + u32 attr =3D CS_AMP_CAL_DEFAULT_EFI_ATTR; + int i, ret; + + if (cal_target =3D=3D 0) + return -EINVAL; + + data =3D cs_amp_get_cal_efi_buffer(dev, &name, &guid, &attr); + ret =3D PTR_ERR_OR_ZERO(data); + if (ret =3D=3D -ENOENT) { + data =3D NULL; + goto alloc_new; + } else if (ret) { + return ret; + } + + /* + * If the EFI variable is just zero-filled reserved space the count + * must be set. + */ + if (data->count =3D=3D 0) + data->count =3D (data->size - sizeof(data)) / sizeof(data->data[0]); + + if (amp_index < 0) { + /* Is there already a slot for this target? */ + for (amp_index =3D 0; amp_index < data->count; amp_index++) { + if (cs_amp_cal_target_u64(&data->data[amp_index]) =3D=3D cal_target) + break; + } + + /* Else find an empty slot */ + if (amp_index >=3D data->count) { + for (amp_index =3D 0; amp_index < data->count; amp_index++) { + if ((data->data[amp_index].calTime[0] =3D=3D 0) && + (data->data[amp_index].calTime[1] =3D=3D 0)) + break; + } + } + } else { + /* + * If the index is forced there could be another active + * slot with the same calTarget. So deduplicate. + */ + for (i =3D 0; i < data->count; i++) { + if (i =3D=3D amp_index) + continue; + + if ((data->data[i].calTime[0] =3D=3D 0) && (data->data[i].calTime[1] = =3D=3D 0)) + continue; + + if (cs_amp_cal_target_u64(&data->data[i]) =3D=3D cal_target) + memset(data->data[i].calTime, 0, sizeof(data->data[i].calTime)); + } + } + +alloc_new: + if (amp_index < 0) + amp_index =3D 0; + + num_entries =3D max(num_amps, amp_index + 1); + if (!data || (data->count < num_entries)) { + struct cirrus_amp_efi_data *old_data __free(kfree) =3D no_free_ptr(data); + unsigned int new_data_size =3D struct_size(data, data, num_entries); + + data =3D kzalloc(new_data_size, GFP_KERNEL); + if (!data) + return -ENOMEM; + + if (old_data) + memcpy(data, old_data, struct_size(old_data, data, old_data->count)); + + data->count =3D num_entries; + data->size =3D new_data_size; + } + + data->data[amp_index] =3D *in_data; + ret =3D cs_amp_set_cal_efi_buffer(dev, name, guid, attr, data); + if (ret) { + dev_err(dev, "Failed writing calibration to EFI: %d\n", ret); + return ret; + } + + return 0; +} + /** * cs_amp_get_efi_calibration_data - get an entry from calibration data in= EFI. * @dev: struct device of the caller. @@ -443,6 +585,46 @@ int cs_amp_get_efi_calibration_data(struct device *dev= , u64 target_uid, int amp_ } EXPORT_SYMBOL_NS_GPL(cs_amp_get_efi_calibration_data, "SND_SOC_CS_AMP_LIB"= ); =20 +/** + * cs_amp_set_efi_calibration_data - write a calibration data entry to EFI. + * @dev: struct device of the caller. + * @amp_index: Entry index to use, or -1 to use any available slot. + * @num_amps: Maximum number of amps to reserve slots for, or -1 to ignore. + * @in_data: struct cirrus_amp_cal_data entry to be written to EFI. + * + * If a Vendor-specific variable exists it will be updated, + * else if the Cirrus variable exists it will be updated + * else the Cirrus variable will be created. + * + * If amp_index >=3D 0 the data will be placed in this entry of the calibr= ation + * data array, overwriting what was in that entry. Any other entries with = the + * same calTarget will be marked empty. + * + * If amp_index < 0 and in_data->calTarget matches any existing entry, that + * entry will be overwritten. Else the first available free entry will be = used, + * extending the size of the EFI variable if there are no free entries. + * + * If num_amps > 0 the EFI variable will be sized to contain at least this + * many calibration entries, with any new entries marked empty. + * + * Return: 0 if the write was successful, -EFBIG if space could not be mad= e in + * the EFI file to add the entry, -EACCES if it was not possible to + * read or write the EFI variable. + */ +int cs_amp_set_efi_calibration_data(struct device *dev, int amp_index, int= num_amps, + const struct cirrus_amp_cal_data *in_data) +{ + if (IS_ENABLED(CONFIG_EFI) || IS_ENABLED(CONFIG_SND_SOC_CS_AMP_LIB_TEST))= { + scoped_guard(mutex, &cs_amp_efi_cal_write_lock) { + return _cs_amp_set_efi_calibration_data(dev, amp_index, + num_amps, in_data); + } + } + + return -ENOENT; +} +EXPORT_SYMBOL_NS_GPL(cs_amp_set_efi_calibration_data, "SND_SOC_CS_AMP_LIB"= ); + struct cs_amp_spkid_efi { efi_char16_t *name; efi_guid_t *guid; --=20 2.47.3 From nobody Sun Feb 8 07:52:31 2026 Received: from mx0b-001ae601.pphosted.com (mx0b-001ae601.pphosted.com [67.231.152.168]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CA6AD303C93; Tue, 21 Oct 2025 10:50:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=67.231.152.168 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761043836; cv=fail; b=MjtLa/3OlyZ3al5fAfsPkl+OZMn5ctyD6sIYBYH1hN+9nO73EKQ3sSurKrjyezYd9oW2FhnK/8TB9TqFtSZwB2Cuun0MASgIqEt7eK7ecaJmIyBW14E1kMFxDmKR2IzYER5GSHorW53g4dC39lH5LgIHNjgrCakWgLV1H40ygog= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761043836; c=relaxed/simple; bh=P1MWqPO3tKGdenYUxbTvvUcxwscYD8bnqSJS1FAXtiU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=uOrcWN7HTUAel8IqK00R6CdNMd178F4lrqFAEfbLNxPt1Bo23O14CeSbvscmoJYdy3DOWvUCe9TftDYE5iRgjy/8EIPVPUN147NRVV63ExEVgozLSbl3pewcBOf9XU+O5KCa1RKcAl2gJfxnQnqg3RvZLs47ELKuWe/CfjKJNN8= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=opensource.cirrus.com; spf=pass smtp.mailfrom=opensource.cirrus.com; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b=cSMKdt1e; dkim=pass (1024-bit key) header.d=cirrus4.onmicrosoft.com header.i=@cirrus4.onmicrosoft.com header.b=nXk0ksxH; arc=fail smtp.client-ip=67.231.152.168 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=opensource.cirrus.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=opensource.cirrus.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="cSMKdt1e"; dkim=pass (1024-bit key) header.d=cirrus4.onmicrosoft.com header.i=@cirrus4.onmicrosoft.com header.b="nXk0ksxH" Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 59L4xtJn2412958; Tue, 21 Oct 2025 05:50:31 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s= PODMain02222019; bh=zNCQlsf1Qw7sQkpt8u710Er7F3pdB79f07UFMQ0OZ18=; b= cSMKdt1e7pBslHXZ0xWLeY+GyXRkjCJEo7LE1OcKb1acM6z1SBc+W8K2uVdSj641 g+mE+tF2lXnoM07vq+miaEQ/Hlh83JmImBP9J3fUd+Bx3V+oCvWaLtFF9AwG8XSp 8KbMkcK0lQTzUvBbfU1MI59ptbLMODpVMPfvua8WSxXqe/PauzPlTStdEAU0jjmb M/ae2wMBponxYliMXPsz5jIs1CJw2Zj5XgOfIwUNMPxgiJiLfl2Y1qMxJ2LmPX/y yFs1qA5CqlZeOIXlKMp+RwZzvLWqt0pdkybAyfJbeuo6E6tg8j40W+btExW41KZf IuyQ+OQiTDahZJHPW/PO0Q== Received: from dm1pr04cu001.outbound.protection.outlook.com (mail-centralusazon11020134.outbound.protection.outlook.com [52.101.61.134]) by mx0b-001ae601.pphosted.com (PPS) with ESMTPS id 49v7aj3eg1-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Tue, 21 Oct 2025 05:50:31 -0500 (CDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=aIUFJhHm6DEsIveuO+xrFY0vPHX9iihBu/GZisNM4cxaiOAO3+thvjNxNlXXrsNjT5dp54+yiBBm14i8ExcyyCi3ww0uGiKUz8+bQxXA3LHlC3z7QAConzZ/Nd/QMEvTMUs1OGRWUqdIeYCebUnzf7KQEAmf1j8toRGIjUtMFqZ4upCgL0s25srWfrW4dUTz4aFvB3P1C4Srif8o6jJ8kYWSRwlCVU1xJ0xOwq6+YhXQRcOxqpCGx70aI1PvfMDtqNviPwIf6mIzo3tx0ARq97PRKrBELA6LO9i02CEDF5fwdfq6go1BROGaxiB9HFUlsbm/0Vcb2bs5FGajf0SgSg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=zNCQlsf1Qw7sQkpt8u710Er7F3pdB79f07UFMQ0OZ18=; b=vzE+oUEUSjXPqXzvU8D3GA28O5tIZbcXwCFSWu8y+gP6EIVEImbIC9GkW15IFCy/uKy318ckXRvrwvQLfKrDCSwLIu99B5cKCQvhKHXSJdJNSsG1GHQCiUnSk4s2doWU49sRM/kbTCew7X/xVbKAYicouqjN7cRmIGNMWTz48ZAGfqOswK5ypIOqq97WuTyQo/Y3wCqhh9WjiQaFnrChLdkkLwC+Uf17wrBeNJCN4Ptr5KrXiR3LcNi4HoLapGG90LpUkk9xaUFU+OW48/K7NdOaMbIfJCFUBs3B6peMS+uNQH8IVn/iacA2fBkzcX8D6i0wtsJpKHXk8/Rfu8Jjbg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=fail (sender ip is 84.19.233.75) smtp.rcpttodomain=cirrus.com smtp.mailfrom=opensource.cirrus.com; dmarc=fail (p=reject sp=reject pct=100) action=oreject header.from=opensource.cirrus.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus4.onmicrosoft.com; s=selector2-cirrus4-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=zNCQlsf1Qw7sQkpt8u710Er7F3pdB79f07UFMQ0OZ18=; b=nXk0ksxH0qxssTRqAOOfBvrW2Rbcwrj7t1TNLJFGEKF0pzDGBZeYIdU1iotLfzkipjcx+K4kHlYEwNVyV3wDProHyUx9mea5Ag6Tq9h56GIWioD5YLw/2Tm7ccd0yFW5xviAT3d69fym9zfzwTtfqjrybOzohG9IhJZGfp8aKdM= Received: from SN7P220CA0029.NAMP220.PROD.OUTLOOK.COM (2603:10b6:806:123::34) by DS2PR19MB9102.namprd19.prod.outlook.com (2603:10b6:8:2b1::20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9228.17; Tue, 21 Oct 2025 10:50:27 +0000 Received: from SA2PEPF000015CD.namprd03.prod.outlook.com (2603:10b6:806:123:cafe::3e) by SN7P220CA0029.outlook.office365.com (2603:10b6:806:123::34) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9228.16 via Frontend Transport; Tue, 21 Oct 2025 10:50:27 +0000 X-MS-Exchange-Authentication-Results: spf=fail (sender IP is 84.19.233.75) smtp.mailfrom=opensource.cirrus.com; dkim=none (message not signed) header.d=none;dmarc=fail action=oreject header.from=opensource.cirrus.com; Received-SPF: Fail (protection.outlook.com: domain of opensource.cirrus.com does not designate 84.19.233.75 as permitted sender) receiver=protection.outlook.com; client-ip=84.19.233.75; helo=edirelay1.ad.cirrus.com; Received: from edirelay1.ad.cirrus.com (84.19.233.75) by SA2PEPF000015CD.mail.protection.outlook.com (10.167.241.203) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9253.7 via Frontend Transport; Tue, 21 Oct 2025 10:50:26 +0000 Received: from ediswmail9.ad.cirrus.com (ediswmail9.ad.cirrus.com [198.61.86.93]) by edirelay1.ad.cirrus.com (Postfix) with ESMTPS id BA409406561; Tue, 21 Oct 2025 10:50:22 +0000 (UTC) Received: from ediswws06.ad.cirrus.com (ediswws06.ad.cirrus.com [198.90.208.24]) by ediswmail9.ad.cirrus.com (Postfix) with ESMTPSA id 8F9F782255A; Tue, 21 Oct 2025 10:50:22 +0000 (UTC) From: Richard Fitzgerald To: broonie@kernel.org, tiwai@suse.com Cc: linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org, patches@opensource.cirrus.com Subject: [PATCH v2 09/11] ASoC: cs35l56: Add calibration command to store into UEFI Date: Tue, 21 Oct 2025 11:50:20 +0100 Message-ID: <20251021105022.1013685-10-rf@opensource.cirrus.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251021105022.1013685-1-rf@opensource.cirrus.com> References: <20251021105022.1013685-1-rf@opensource.cirrus.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SA2PEPF000015CD:EE_|DS2PR19MB9102:EE_ X-MS-Office365-Filtering-Correlation-Id: 8c71f0c8-f3c9-4041-6cc4-08de108fa50e X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|82310400026|376014|36860700013|61400799027; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?XMxGnfM6/IrmbJE48LChngX1lrNMjIsIHQcjn8U8hKkS+3lm819BBKBwJU/D?= =?us-ascii?Q?nyXrw72tEZErIkXWoVd7sv4DKw6Qa5FMy6G8KR7cEA3p4HTxl9L4ilKAvFXW?= =?us-ascii?Q?8DooEvdx5s5sJjcJX/In5oUu8QeboxtBeEXN2iGSmKj9Y73TowX1P/lzTZFs?= =?us-ascii?Q?fAoVMXBy3e3DoPuA8duPo/sopY9/u45NpsPVs/NeXutI6j73Iic+1pkSXMf0?= =?us-ascii?Q?Ey7LHuw6pULT/fdai3nELkJZSYAPdhaHOMsO7QBKISjxdiwuLhlLEtb6HwAR?= =?us-ascii?Q?94IaEuY9cYlRZNnDJnsdPBr7HWXwJoctxWr/2+9DGC/EvYSxcUYxNMFnWXnv?= =?us-ascii?Q?HSxgMa1nr+n+bRQme1mDd6vPIGyW5Wx13dFnuPzX4lCVI/TYah3FaTW9hymM?= =?us-ascii?Q?OEcXCiRNc1Q8gBG5TYqQjg/NY/HdL/qpUUIHDKUHIiTBR0KipE+x5EXSPJS8?= =?us-ascii?Q?CJFwDlkIKni4x6bstJsVYTLw5WSdhdyx8jOCAB6OXK6mH1wFmPrG7ThKFzOr?= =?us-ascii?Q?dW/VDMVkbQ9pO2xkkgOvAnkTof5rMccA7mRw4c7pQx4PgUC/Mv2NDY3t/spA?= =?us-ascii?Q?QCOb4xYVoTGmGOiViM4Wwh9/GY03uPL8hobaUndrx3f3WKAhErMYRU9v7ndg?= =?us-ascii?Q?zhj2Ve/OwYDLbJTmBFutnSgAo/bmWFRi9+WGLnaDNbvm6NnBA2xh84mVQd4b?= =?us-ascii?Q?3/XQjosNsFJlNGwsd++NmnAyw/rgaIpo04i2kBkq7XIfWbIY9ynO/3yejfqR?= =?us-ascii?Q?bobvjOK14lBXkhhfMkyK+byjfqFhKVKQQ4xOlBmOAkOcNPQjooLjDwOA0Fem?= =?us-ascii?Q?eWp/lH8z34oExlqJaRtUo4cY+aeNBGkjUVSOe6WGjI0bRnUAdSJC8xTGUrt2?= =?us-ascii?Q?Vw36zb748bE7tZnLv22BJJevdKU3i5DgPLklz2fuLl5zPTmQUzC/tw24PTZ1?= =?us-ascii?Q?AlesMci0q7MOHeA757pGLTInxqs0rBPD552ZDWgpZCg0EVlojfTbo51a/NpZ?= =?us-ascii?Q?B2dXWfOKZscwTTF87WVnZJp5jyMD+UKQcHUieQ68D90M9yaZceZLBcsH9ZZh?= =?us-ascii?Q?qcay8njwh4XYBJQBtPSmTLEvVjfxhUBGHTGEUM30frnGd6l76F0ZV4Ttb0vD?= =?us-ascii?Q?eqg4Nglq/pPIVLh9/nvBi21rCdh//4JPmdqjLxuv2RYznRgS/stje5MgZR25?= =?us-ascii?Q?FGdaSfr1NN4h/NBV7i0u3A6Mm2vM1ZJNL1mTxAkBxk0BrOXJU/VweLJikhXM?= =?us-ascii?Q?NVFD417s/6pTCu+x35UTBDSf1L248ZAgUHTICKURCMp5kWgwbnCXb7QZ2aZx?= =?us-ascii?Q?2mkdfO+s9Li6qJ/NEzKbRc9FyUpSLis25htahcreuqE0l0n7RT6l52rVFxsm?= =?us-ascii?Q?F5Qt3owTRwTbLpdak1EKQaZ+u+aEmyoRvYuMKzsJYPXGFUc121l95v1FFRNI?= =?us-ascii?Q?kiflXjbNGO2OIxgoXchW66SDFUzGopfFlE6LEfKXNVmRwUE75ialGPh2N3+K?= =?us-ascii?Q?cIb3TW5RWMmOZYAPjXNnui83Txo8S0DZU2jN5iYRdHrJ+bFs/WVGOAxK9eje?= =?us-ascii?Q?jUkYsR/s4yYQMP8OAPs=3D?= X-Forefront-Antispam-Report: CIP:84.19.233.75;CTRY:GB;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:edirelay1.ad.cirrus.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(82310400026)(376014)(36860700013)(61400799027);DIR:OUT;SFP:1102; X-OriginatorOrg: opensource.cirrus.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Oct 2025 10:50:26.5915 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 8c71f0c8-f3c9-4041-6cc4-08de108fa50e X-MS-Exchange-CrossTenant-Id: bec09025-e5bc-40d1-a355-8e955c307de8 X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=bec09025-e5bc-40d1-a355-8e955c307de8;Ip=[84.19.233.75];Helo=[edirelay1.ad.cirrus.com] X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: TreatMessagesAsInternal-SA2PEPF000015CD.namprd03.prod.outlook.com X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DS2PR19MB9102 X-Proofpoint-ORIG-GUID: fMiLW9EI2RLJ1qZAuHmuXfOB87GM5qYU X-Proofpoint-GUID: fMiLW9EI2RLJ1qZAuHmuXfOB87GM5qYU X-Authority-Analysis: v=2.4 cv=bdNmkePB c=1 sm=1 tr=0 ts=68f76577 cx=c_pps a=TszpKlPPvK6rXl4+XYbYdQ==:117 a=h1hSm8JtM9GN1ddwPAif2w==:17 a=6eWqkTHjU83fiwn7nKZWdM+Sl24=:19 a=z/mQ4Ysz8XfWz/Q5cLBRGdckG28=:19 a=x6icFKpwvdMA:10 a=s63m1ICgrNkA:10 a=RWc_ulEos4gA:10 a=VkNPw1HP01LnGYTKEx00:22 a=w1d2syhTAAAA:8 a=8cExK4-QNj-zMObyTR0A:9 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMDIxMDA4NSBTYWx0ZWRfX9AgNoxfDPwMW 2wynpM5wIRm9TnIO+Qn2v9m+YmyztqwtQb/SWbkpvnnGmCcdTxpIWac6/svXzdk9Wr6ocDASNJt wbVVC0ZAfWy4/UscOH9eUBRTCBBClAfcXLDbv+cEQsq7tRp77z3mjDJH8sFQjz+5LFG6Jn7VVuf Ji5QcUSDpDNdNoIEYzLAExBYmsDfh9Cw+2zDbNSyfag+kXhuwmY+/C2jD9w0YRRRjEYlaSAYdVD RKLK7bCxZNMrdFoyuXVtWzTuB20Sl/ye4SiqFUOqPnoePSPhkZvZCZSdSEYzxxMr15w5s0j3rrs z0uvWcSCQ+kGAi3Y52ZnO9wmZmUS7fqknbelGFWcum9yIVuYh/JePeA0e+CCTQ8GPoi8lH4AWFn vZfiKGDZ/vl8twrS55d8HdcQu2aFuA== X-Proofpoint-Spam-Reason: safe Content-Type: text/plain; charset="utf-8" Add a new command 'store_uefi' to the calibrate debugfs file. Writing this command will call cs_amp_set_efi_calibration_data() to save the new data into a UEFI variable. This is intended to be used after a successful factory calibration. On systems without UEFI the write to the debugfs file will return an error. Signed-off-by: Richard Fitzgerald Reviewed-by: Takashi Iwai --- Changes since V1: - Rebased onto the new debugfs callback implementation - Only code change since V1 is to increase the size of the local char array buf[]. include/sound/cs35l56.h | 1 + sound/soc/codecs/cs35l56-shared.c | 21 ++++++++++++++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/include/sound/cs35l56.h b/include/sound/cs35l56.h index 349b896ee737..82559be0f249 100644 --- a/include/sound/cs35l56.h +++ b/include/sound/cs35l56.h @@ -321,6 +321,7 @@ struct cs35l56_base { bool can_hibernate; bool cal_data_valid; s8 cal_index; + u8 num_amps; struct cirrus_amp_cal_data cal_data; struct gpio_desc *reset_gpio; struct cs35l56_spi_payload *spi_payload_buf; diff --git a/sound/soc/codecs/cs35l56-shared.c b/sound/soc/codecs/cs35l56-s= hared.c index eeb830e3f743..bbacac6bda81 100644 --- a/sound/soc/codecs/cs35l56-shared.c +++ b/sound/soc/codecs/cs35l56-shared.c @@ -1105,9 +1105,9 @@ ssize_t cs35l56_calibrate_debugfs_write(struct cs35l5= 6_base *cs35l56_base, const char __user *from, size_t count, loff_t *ppos) { - static const char * const options[] =3D { "factory" }; - char buf[8] =3D { 0 }; - int ret; + static const char * const options[] =3D { "factory", "store_uefi" }; + char buf[11] =3D { 0 }; + int num_amps, ret; =20 if (!IS_ENABLED(CONFIG_SND_SOC_CS35L56_CAL_DEBUGFS_COMMON)) return -ENXIO; @@ -1125,6 +1125,21 @@ ssize_t cs35l56_calibrate_debugfs_write(struct cs35l= 56_base *cs35l56_base, if (ret < 0) return ret; break; + case 1: + if (!cs35l56_base->cal_data_valid) + return -ENODATA; + + num_amps =3D cs35l56_base->num_amps; + if (num_amps =3D=3D 0) + num_amps =3D -1; + + ret =3D cs_amp_set_efi_calibration_data(cs35l56_base->dev, + cs35l56_base->cal_index, + num_amps, + &cs35l56_base->cal_data); + if (ret < 0) + return ret; + break; default: return -ENXIO; } --=20 2.47.3 From nobody Sun Feb 8 07:52:31 2026 Received: from mx0b-001ae601.pphosted.com (mx0a-001ae601.pphosted.com [67.231.149.25]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AB065320391; Tue, 21 Oct 2025 10:50:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=67.231.149.25 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761043836; cv=fail; b=JVwTZ9wlja5I3Bzp5fZSqjbdq2kuTV+RWsQB25zEG2YJWwNk31hbHy8G4BVHFme4M2VcVI9m0tvDtWcunETd3BlHz7VE62uY5UQmTBeesibT9Hp3yKTLWeA3wfVBQAI1pHUqZtBKTE3AbpV4edER8jKjDdiEN8jkNoEbew/X+so= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761043836; c=relaxed/simple; bh=fskXtZg2QWqzpCit0v/eKpCkJ/p9j3CQikCzS5gG8qE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=F9/QDzDhpivYZHUrSqhRt6oOD7hHgesPwSf2b5jCHwDyDhch9kIMPyxSg/lAgEAoAQGbtGpY4j+9I4knwOBSobEtlsBFKHeAnJfMxNU/pRbFfQ8JtkTCydyI0PEGU7FlswCgiW788M41FS9WabVzELkncdwqLHYUt2MjrP7TFTg= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=opensource.cirrus.com; spf=pass smtp.mailfrom=opensource.cirrus.com; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b=CXLmk7Ic; dkim=pass (1024-bit key) header.d=cirrus4.onmicrosoft.com header.i=@cirrus4.onmicrosoft.com header.b=K5yG3DC3; arc=fail smtp.client-ip=67.231.149.25 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=opensource.cirrus.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=opensource.cirrus.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="CXLmk7Ic"; dkim=pass (1024-bit key) header.d=cirrus4.onmicrosoft.com header.i=@cirrus4.onmicrosoft.com header.b="K5yG3DC3" Received: from pps.filterd (m0077473.ppops.net [127.0.0.1]) by mx0a-001ae601.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 59L4jHCt952328; Tue, 21 Oct 2025 05:50:30 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s= PODMain02222019; bh=MFjJ87ZyfeVITZTbJxj9KihRa221EyZNB537gqjCSqU=; b= CXLmk7IcV83GKqUrjwhoWYiVr2dJD9g48mzUkMheP4OKp2udd6tF6A5AjlBrgOPp Uswu+x/cpfSEidCiRlSO/9VhLUlp6ZhAwxsWkXhc8wfCSrLQva1vH9I8pDH/a4qp t4h8aAFaClwj7Gdrk+1YjBl/6B6ZcK7HRH0Dqc6uS45YGh7Gjm1jwOzL43ckIVhQ R7HPc6wkExENOlu7lo0+3yhRrlYWi1XTDLMH6IJNP3cEkpGBT2Kas7SSpJDhWK2E buEXU/5m9B4ckBWxYHN9n4kFSGmJEdXoDYdY3qeOOzaM0P3/1ogDP14klSWOudga duAUe4U4VfyEgquEhKMocA== Received: from ch1pr05cu001.outbound.protection.outlook.com (mail-northcentralusazon11020101.outbound.protection.outlook.com [52.101.193.101]) by mx0a-001ae601.pphosted.com (PPS) with ESMTPS id 49wnc4sdqj-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Tue, 21 Oct 2025 05:50:30 -0500 (CDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=w2P+lEViM1G3MUMUNaP8CT88fCH40OuJBIdL9PcOIZKxJWOtf3JVa4aMsWW8ndWHPORYrXdCTBIRixOxuHVe4Mb1JJkYJIMqxrnxlnFMSrZMZJGGKH6D4pQ0Ic1BkUd8EsE674YaVMz5tqoNnnnuzMntHBSK7sRh5jtYFN9WVmcPtI0WzcNU0nS1pvPBAflakiNxESNDPqKAQayAk90rJ7ZVz25c5bKv9Vlnwf2lI7zKXjtWD6rl55NaoE6zuTPykqP+nokxroC7fhvELiFWkpizts8GGETgc8HYYJGcYPREVryIhlH/NMeL0GFvipZIx12ByxNjm3uevpMyjmcmsg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=MFjJ87ZyfeVITZTbJxj9KihRa221EyZNB537gqjCSqU=; b=cpQyylNe9Hi3jp4Z8Nyc6qUCKd2nSXFsLdVMVALBho4c3pvw+x9uDjf9lJOyx0H1YhIq0wcDvTso6/JBE5G6OQJh7wqNVrtdAG0a5fl6bA8Qk3jnnrglg059zvxieb5LgB1Qy/UOnbahkXIuSlIlwKK9tu9v9Fdnx9j7isoJ6hU6VEsnEsOPkxFAioC9RZOc+B3qkf9xgigG5B0+7X3Fio31hMLFVNnCQx6359RXNSW8n4UWzIWm/X+sLYL+90knGgTrij2a+m5FVBc2Bm6K1DR1pKfKNiiU43Lka4rFBO4xYtIqQwkUiU3MlrJYkG3k1Tv7dbZ2H++p5LiotZQhsg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=fail (sender ip is 84.19.233.75) smtp.rcpttodomain=cirrus.com smtp.mailfrom=opensource.cirrus.com; dmarc=fail (p=reject sp=reject pct=100) action=oreject header.from=opensource.cirrus.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus4.onmicrosoft.com; s=selector2-cirrus4-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=MFjJ87ZyfeVITZTbJxj9KihRa221EyZNB537gqjCSqU=; b=K5yG3DC3QUt9wl04yrEbWiWw2SNH+AbClKCPu+X2s4Ylu9MQIPRX4JFwfg49EvnED0o8TV9zOTuf3foPwHRB7HhaOL1YXd5mhVzAkfcRPBYya2hCbLHFnp2Vs4AhXU1mrHKWBrSp4yBaia+tnuAnggd4c28teyt0HYwjHyBQI6E= Received: from BYAPR11CA0098.namprd11.prod.outlook.com (2603:10b6:a03:f4::39) by CY8PR19MB6916.namprd19.prod.outlook.com (2603:10b6:930:60::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9228.17; Tue, 21 Oct 2025 10:50:27 +0000 Received: from SJ1PEPF00002326.namprd03.prod.outlook.com (2603:10b6:a03:f4:cafe::37) by BYAPR11CA0098.outlook.office365.com (2603:10b6:a03:f4::39) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9253.12 via Frontend Transport; Tue, 21 Oct 2025 10:50:27 +0000 X-MS-Exchange-Authentication-Results: spf=fail (sender IP is 84.19.233.75) smtp.mailfrom=opensource.cirrus.com; dkim=none (message not signed) header.d=none;dmarc=fail action=oreject header.from=opensource.cirrus.com; Received-SPF: Fail (protection.outlook.com: domain of opensource.cirrus.com does not designate 84.19.233.75 as permitted sender) receiver=protection.outlook.com; client-ip=84.19.233.75; helo=edirelay1.ad.cirrus.com; Received: from edirelay1.ad.cirrus.com (84.19.233.75) by SJ1PEPF00002326.mail.protection.outlook.com (10.167.242.89) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9253.7 via Frontend Transport; Tue, 21 Oct 2025 10:50:26 +0000 Received: from ediswmail9.ad.cirrus.com (ediswmail9.ad.cirrus.com [198.61.86.93]) by edirelay1.ad.cirrus.com (Postfix) with ESMTPS id BD623406569; Tue, 21 Oct 2025 10:50:22 +0000 (UTC) Received: from ediswws06.ad.cirrus.com (ediswws06.ad.cirrus.com [198.90.208.24]) by ediswmail9.ad.cirrus.com (Postfix) with ESMTPSA id 9286482255C; Tue, 21 Oct 2025 10:50:22 +0000 (UTC) From: Richard Fitzgerald To: broonie@kernel.org, tiwai@suse.com Cc: linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org, patches@opensource.cirrus.com Subject: [PATCH v2 10/11] ALSA: hda/cs35l56: Set cal_index to the amp index Date: Tue, 21 Oct 2025 11:50:21 +0100 Message-ID: <20251021105022.1013685-11-rf@opensource.cirrus.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251021105022.1013685-1-rf@opensource.cirrus.com> References: <20251021105022.1013685-1-rf@opensource.cirrus.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ1PEPF00002326:EE_|CY8PR19MB6916:EE_ X-MS-Office365-Filtering-Correlation-Id: 73deb663-58d4-451e-fb54-08de108fa539 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|61400799027|36860700013|82310400026|376014; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?2KbESIEfdaELc6i+d6vaMtagezRNVqhP2eKet1eESxbs2RBZhVMQhV42bCpC?= =?us-ascii?Q?D6rDz0VbeKjuNmClrDqBkFZ/TAkG3FwfUz4jA4uG3uVxQp4zjctKYZaqRu/1?= =?us-ascii?Q?f/Gihut1TdN2Lnj411Ga6tDFx0M7wTILBsQ6FaZDVUJeMRG5orWVdcwSBPf/?= =?us-ascii?Q?OmdfneIJDjMZxUy/R5HTuptSLkb/xUQcCnk4cWa5yWLbyrlHTEPk656SgrmC?= =?us-ascii?Q?MNscCfixXMQCvSssZBKBBw4hu+MMmKPdcaJ4Fc1j90I3Qxn4gtXDpWVHBlTJ?= =?us-ascii?Q?n+l6XBIGp+WlxIQKzwPKsebYWNg10SB5IGZ7sNveGauFyzS1eA+qG9H6/7j/?= =?us-ascii?Q?+fVGjZh120sPKgaZGToLjuyCa+Sn5iOstQVBbTsgqJlFJmMzHRKV95lzPslD?= =?us-ascii?Q?JzKhHFM6Y4QJHF4S8I0aACj5W4vtrYCZ+1yvTJJcj0ANHetRK6xKs9ykHMjU?= =?us-ascii?Q?Fs0w5mTfs7uzcFNa3v3mjzHoo2c8Jz7g59n5rTcQWyoiJtAeKu2wLtFDmQje?= =?us-ascii?Q?gKFQJHbPxOe7Vnq3x5Mt1EvUnxYHhjDOu8ddE4HrinZ37OUqL022hnMXlX0Z?= =?us-ascii?Q?I7FDuJKCd+uJ2Tx5Rtiy4R04HCy8C/GV97YEDImCpbLbeXUQstt0ASEfMw/b?= =?us-ascii?Q?eqLpKxOoYM5ZcrHpNiJl5liD5ESMHpnRIMy2HbLJdKO/1dnnrbd8ZuKC50oH?= =?us-ascii?Q?dMPVj20KDM5d0UX48OtbnLIeQiP3DA4imCyJKUYmzHdWApuzEg/XFY8oIh1E?= =?us-ascii?Q?hFAL3a2i1l0+9CfL94hJWSZ1tiVTD1BbJC3bIMib8vGqCuOd3Fk9TXO30BtF?= =?us-ascii?Q?di3ooznSL00/ZdFAalCz2hBQMH+iGo+PI4CI+KTE70vCYjWGTmbj/Q6YL5T4?= =?us-ascii?Q?l+K2fogQPF1z44VfGB8nHThRvFANuYb8KpiUPVVjO5KQUv70OybUTTIq167s?= =?us-ascii?Q?O3qHibHhTyLz7YzQgvGEYlj5TytFs21XMNS7vyZVpskhx+inzt8ZxR9xy3mc?= =?us-ascii?Q?UlJVqmGmMKZ4W7qT6Q+PZiLFyqLY9qx0jsGE/EwpE2ozG6Ml3xAB8Qf+OJ03?= =?us-ascii?Q?BFC8nDxV/qyRHO1LHSo2153POCfEaZxFtsCJJz6FeMLHQ4Jf0lOduX682LeP?= =?us-ascii?Q?KvTLCXUZjfNhM8STVdvBQV2W645oAhFKG0hja1Wy063sraplJVndHg0Ov8lQ?= =?us-ascii?Q?UDt1nGbxfXEYoLRhTPCx7nonngF89J4CKCVXQNjI4zvHhWh2a09RIjl94XGO?= =?us-ascii?Q?Ecta127Hq3lBaJTNKM/jqsAE8ehSWmOw0u0h4Ktz0HShCfVOMhp1REL6ryD0?= =?us-ascii?Q?2N/T+ml8dLYIRMIwbKSB2OkkSQEHgqZRtUawu+3NtpPDdOafvnFmbCJBbRQu?= =?us-ascii?Q?cdJvS9GN0dgvXVLIjzE0Ds0m+6F1Me0rfzDmbSdEMnFbSOQdZ6F1SabyuroJ?= =?us-ascii?Q?0mhTQYlXh8LOw0qcVyBUWPC9FgWvAB0Rwmw46HB/ztjq4as9v2D4jg3eKDLq?= =?us-ascii?Q?P/NpDCAgbDPmGeIgm5KRS5jfi0ZmZKn8moDh9tvtLMQbTQ1bGhACZrRaQmsg?= =?us-ascii?Q?LANiH+v8S5VhIBmznG8=3D?= X-Forefront-Antispam-Report: CIP:84.19.233.75;CTRY:GB;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:edirelay1.ad.cirrus.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(61400799027)(36860700013)(82310400026)(376014);DIR:OUT;SFP:1102; X-OriginatorOrg: opensource.cirrus.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Oct 2025 10:50:26.8193 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 73deb663-58d4-451e-fb54-08de108fa539 X-MS-Exchange-CrossTenant-Id: bec09025-e5bc-40d1-a355-8e955c307de8 X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=bec09025-e5bc-40d1-a355-8e955c307de8;Ip=[84.19.233.75];Helo=[edirelay1.ad.cirrus.com] X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: TreatMessagesAsInternal-SJ1PEPF00002326.namprd03.prod.outlook.com X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY8PR19MB6916 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMDIxMDA4NSBTYWx0ZWRfX4D1o8pk7Vqkn VtRs9cNh6s3QHjLrisogFAiDa9pKEC3RMm1eZaqGKO3Hd/cfOJjQ8nIvaWlJCpUkByHc+Aej+wB V02NvxeV/NJuDQ6vuL8VvgBVrLHk5owUlSuxkgcqTjAsQLR9nP51VCq/OxpBrR9bax/z3CFX7b9 ICRhlqF+3Dg5cv1RlwhXKGm899c0tFELtTUY3zVuSXtMDf9KTSXZGzwh4ArQrjwAFHRyDcpJYAo HDLZngXce4G8h/3Uf1iPq9t/1F6Zl0pZedF6/DInxlgKXwu6qTsxV9doB1h7U2o02qyxIWJmS2d 3enyvn8lm9uA58eOr3Lv7wJgiI2FrKeD6CjLCEirnclqoWjDQA9M1N+hH63YKowoj3CGsZYXc5s PtatXOOjzqgwhoO+gYmM4npIq3QqZw== X-Proofpoint-GUID: Dq5Asd9eaN3-Wluace_SwmgiPclCTa26 X-Proofpoint-ORIG-GUID: Dq5Asd9eaN3-Wluace_SwmgiPclCTa26 X-Authority-Analysis: v=2.4 cv=bf1mkePB c=1 sm=1 tr=0 ts=68f76576 cx=c_pps a=IAlGFxvWO5AZskdmYTP3vQ==:117 a=h1hSm8JtM9GN1ddwPAif2w==:17 a=6eWqkTHjU83fiwn7nKZWdM+Sl24=:19 a=z/mQ4Ysz8XfWz/Q5cLBRGdckG28=:19 a=x6icFKpwvdMA:10 a=s63m1ICgrNkA:10 a=RWc_ulEos4gA:10 a=VkNPw1HP01LnGYTKEx00:22 a=w1d2syhTAAAA:8 a=yyqevtf6Vn7-8GcW_JgA:9 X-Proofpoint-Spam-Reason: safe Content-Type: text/plain; charset="utf-8" Set cs35l56_base->cal_index to the (zero-based) amp index derived from cirrus,dev-index property. This is so that factory calibration data will be written to the UEFI array in the slot equal to the amp index, for compatibility with the Windows driver. Signed-off-by: Richard Fitzgerald Reviewed-by: Takashi Iwai --- No changes since V1. sound/hda/codecs/side-codecs/cs35l56_hda.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/hda/codecs/side-codecs/cs35l56_hda.c b/sound/hda/codecs/= side-codecs/cs35l56_hda.c index 03f565312459..f7ba92e11957 100644 --- a/sound/hda/codecs/side-codecs/cs35l56_hda.c +++ b/sound/hda/codecs/side-codecs/cs35l56_hda.c @@ -1154,7 +1154,7 @@ int cs35l56_hda_common_probe(struct cs35l56_hda *cs35= l56, int hid, int id) } =20 cs35l56->base.type =3D hid & 0xff; - cs35l56->base.cal_index =3D -1; + cs35l56->base.cal_index =3D cs35l56->index; =20 cs35l56_init_cs_dsp(&cs35l56->base, &cs35l56->cs_dsp); cs35l56->cs_dsp.client_ops =3D &cs35l56_hda_client_ops; --=20 2.47.3 From nobody Sun Feb 8 07:52:31 2026 Received: from mx0b-001ae601.pphosted.com (mx0b-001ae601.pphosted.com [67.231.152.168]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7D9E232E12F; Tue, 21 Oct 2025 10:50:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=67.231.152.168 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761043844; cv=fail; b=I8zk2YvNh2+vmZursy+HiZ3s3RCf2eXKqkahD3paW7/56kq/w9svyxdn2S/izj4rSBT37xJYWXW5Ayy2MkIaM1tGR89QS6D6UU7BmZ6Iena4BpR/gV0YOEUrbd4jrrOfzm4mPB12znvijtyMXVoi/2S6oKtcf5nECqXjIkcP+nw= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761043844; c=relaxed/simple; bh=0ZEL86kBkWLGw7UC+OwcengFF/nzBppifdtSs8fuAYc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=KkYkHQXs+Ai+aqCheIpck6YHR3/3Eok/x1dNcOarJSWiFWtFcmPYAE2z1/KvpgL8RzZCc7wO/k5mM2N0snSLyg3FA0WKM6k8rVdblaWUXk2GiOH5d3mAO+ZEAothx+xkJB60Ai0Q+WdLWPB3FksJ90Q3m7j/iekhv1G2xb6SlWg= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=opensource.cirrus.com; spf=pass smtp.mailfrom=opensource.cirrus.com; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b=oNdCZHw/; dkim=pass (1024-bit key) header.d=cirrus4.onmicrosoft.com header.i=@cirrus4.onmicrosoft.com header.b=t23WU2vt; arc=fail smtp.client-ip=67.231.152.168 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=opensource.cirrus.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=opensource.cirrus.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="oNdCZHw/"; dkim=pass (1024-bit key) header.d=cirrus4.onmicrosoft.com header.i=@cirrus4.onmicrosoft.com header.b="t23WU2vt" Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 59LASk2E2958765; Tue, 21 Oct 2025 05:50:32 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s= PODMain02222019; bh=Ws9njbi6cPnvmUlP4d3RwhxBMnic1Q+r4SD6pIZKl4w=; b= oNdCZHw/gLbW5b3z8b9u/w9XAnD7MuaX8WHuh/Ea+Zbif10KkoEKSUGWB+AIRgOG z6OfO9fWe+in1mN6Cdqapjra28zaI/834Wpje6EFi8kzVOOvh8/UdmAP1azk/uak Yj8nC+t/e9jUOhD6vBC7YoQAgrw1rnRA2MNebSnpJexCAxyCdTDWwJ+SrGerM2+e 7aHvbUq6JWcqYaSAYuBXvPtmhUhgTcU/2RKM22QPyUftj3P3lTCFyGgJ6iWCRm2v TkeOIo79BctJ7TcQnc8pRL3iqqnf9oiEsDbobUEk9HDUyUpEZ3SIgHwIcMlbdFKb BFFmzyzWpepgKosjALuEVg== Received: from cy3pr05cu001.outbound.protection.outlook.com (mail-westcentralusazon11023140.outbound.protection.outlook.com [40.93.201.140]) by mx0b-001ae601.pphosted.com (PPS) with ESMTPS id 49v7aj3eg3-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Tue, 21 Oct 2025 05:50:31 -0500 (CDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=yTa1HRvK/5LlIB6ijFSO2LGtqB6G0sj/Ukl8VtEAL+e2qSb0TrI3zQhPq8fvJHTwjDj4Fp8pps8aNxxSdyDo1hjNrFoxMsQcCog3G8DJYoK9VO6F3zSfIPsS8od29ZkUYgNxRUiFJ+fpNN7P4vjNsSf8x5XCCsGF8a3az9CMeA1d13MEpV9EmqWVogEJ4eIY3WRsi/UNHdmpTbLXzi6YxHEGLfE9n5T9BqX3Z+MVzGGOYweWxjHR5YmwywXWI5nQ3/2um0ncp7N4zJEJ1gFO5EoKPdDyYx2xPCYnLn4A3gz3g3J1bDZxiZgzww1h7FDT10CBy/0nXISlPYxoD7xfdw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=Ws9njbi6cPnvmUlP4d3RwhxBMnic1Q+r4SD6pIZKl4w=; b=SERLfXXvXkxf9R3ul4sCU3U1AjwKY+OeiYpC/SUWiWLUMEGAazev8sCYkhqAP76xm3pEWlKCPSa55O5IJUMxHwAb4z1eHglUxram25/YhIUPQ1W5z9bx64u6ln1da5vqqZYb/dAyViMGt4U8jpLdv0+CPPNmD69+6QzNB1YGufjZSoP/2rgxEa1uCEui2wECV1fhfo6SHWoyyjsm46ubqXaIcZXh+JKoawelh9w1yi+G3w03E1Z5nTS6HknGcSHpcCzmleh2N+rgI13YAjwBSZkMEIB3OsAMJcHD4ErvutFAZKKa/HM/heADiH1HUsQEQsIa1yRop7NUrTBA3ljftQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=fail (sender ip is 84.19.233.75) smtp.rcpttodomain=cirrus.com smtp.mailfrom=opensource.cirrus.com; dmarc=fail (p=reject sp=reject pct=100) action=oreject header.from=opensource.cirrus.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus4.onmicrosoft.com; s=selector2-cirrus4-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=Ws9njbi6cPnvmUlP4d3RwhxBMnic1Q+r4SD6pIZKl4w=; b=t23WU2vtf0TUK8cNQKOVcm4SlymLwY2E6yLFzE2CSl9hPrJt1aPvaQCRZ5n/o01K8xW8rbbOi1UcR3AEPJbhsxRsXb8ga4s+u/BTQ+FW4kAGTw1PMOgR63tfvfvPGxKoMCLU3sULiZe3Hg0Vdc2lSc5tXyDRIgFP92T7RtK5+WA= Received: from BL1PR13CA0209.namprd13.prod.outlook.com (2603:10b6:208:2be::34) by MW3PR19MB4284.namprd19.prod.outlook.com (2603:10b6:303:44::20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9253.12; Tue, 21 Oct 2025 10:50:28 +0000 Received: from BL02EPF0001A0F9.namprd03.prod.outlook.com (2603:10b6:208:2be:cafe::9d) by BL1PR13CA0209.outlook.office365.com (2603:10b6:208:2be::34) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9253.12 via Frontend Transport; Tue, 21 Oct 2025 10:50:28 +0000 X-MS-Exchange-Authentication-Results: spf=fail (sender IP is 84.19.233.75) smtp.mailfrom=opensource.cirrus.com; dkim=none (message not signed) header.d=none;dmarc=fail action=oreject header.from=opensource.cirrus.com; Received-SPF: Fail (protection.outlook.com: domain of opensource.cirrus.com does not designate 84.19.233.75 as permitted sender) receiver=protection.outlook.com; client-ip=84.19.233.75; helo=edirelay1.ad.cirrus.com; Received: from edirelay1.ad.cirrus.com (84.19.233.75) by BL02EPF0001A0F9.mail.protection.outlook.com (10.167.242.100) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9253.7 via Frontend Transport; Tue, 21 Oct 2025 10:50:27 +0000 Received: from ediswmail9.ad.cirrus.com (ediswmail9.ad.cirrus.com [198.61.86.93]) by edirelay1.ad.cirrus.com (Postfix) with ESMTPS id BF6C8406578; Tue, 21 Oct 2025 10:50:22 +0000 (UTC) Received: from ediswws06.ad.cirrus.com (ediswws06.ad.cirrus.com [198.90.208.24]) by ediswmail9.ad.cirrus.com (Postfix) with ESMTPSA id 96FDE82255D; Tue, 21 Oct 2025 10:50:22 +0000 (UTC) From: Richard Fitzgerald To: broonie@kernel.org, tiwai@suse.com Cc: linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org, patches@opensource.cirrus.com Subject: [PATCH v2 11/11] ASoC: cs-amp-lib-test: Add test cases for cs_amp_set_efi_calibration_data() Date: Tue, 21 Oct 2025 11:50:22 +0100 Message-ID: <20251021105022.1013685-12-rf@opensource.cirrus.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251021105022.1013685-1-rf@opensource.cirrus.com> References: <20251021105022.1013685-1-rf@opensource.cirrus.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BL02EPF0001A0F9:EE_|MW3PR19MB4284:EE_ X-MS-Office365-Filtering-Correlation-Id: fed726e5-7038-4616-64eb-08de108fa59f X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|82310400026|61400799027|36860700013; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?xy7M0S9V/64K/qk/g/A6SPasRLSQQb73I13xS1YbUWGXhq5pgjbP5IsiijeS?= =?us-ascii?Q?2wVlqld2lokAf5P/oVHWQFvX7XFxqv6kNmbwt4ZvrEeNprDTcuvibS4OR/oK?= =?us-ascii?Q?bs/vTBcF2jDrERIr0ik8S5Nf9MI01DR4UC2ijm30jwhlVz5eZMeih1A8ca+5?= =?us-ascii?Q?YwjfCVfxXustK4jpQHnSEEKvKixZFx40g/2bIBMgHEif85MnslQs2/uWvvQt?= =?us-ascii?Q?349hbLuTq19ryoBMIobDd2kLrZ89kfcAozLx33Pf8LvwxErBu8hT//3VUewu?= =?us-ascii?Q?4er9M7Gi89EVzN9z395/di6TKTLc7dRg3eY+SLQIsYJxvUank/OLozpREc4u?= =?us-ascii?Q?8pCJ/ZyABTgN+VsfuVZSYlMFKZ2Xh4zQXeAlvJ7kymzo1SApKIHs7M2/j3j7?= =?us-ascii?Q?w1kCoc9wtHkLQiR4iYySE7xrtrGDmTWZzJtTv1PBOfCa9by2iYaMM1yH83Kf?= =?us-ascii?Q?msvKA9HEyb4BCrJYTrP3Oqly82H5bVo4Y6MM6T8YJdspd4jF1ad5Fx2dmbDM?= =?us-ascii?Q?BNcZcRd9UxN8xyRfu5CNtLf9fz2a/MDzSjou4Xq51gMgKe7OJvYzEGshEzO3?= =?us-ascii?Q?9UYoeCs/p1jqjsAVmhTnDuWO6g76bDNwfapkV9cy2BRc2m65XLoyP4hvMJQ5?= =?us-ascii?Q?FRR8CSLHKdLHQ1Yx1dgg/UMkoR33RXlCWSWtv0UFsPC6Q3lmT2oIRDoQBL0c?= =?us-ascii?Q?cHGz13CMK3RJEArAGdaQsl/3dD82I7YqIpd/j9tcxwqAaRFi4X0ytujdx386?= =?us-ascii?Q?sv2gkdW1j5XH6cgbuPaDuLu/9S4kVaY1xBzMzHnaqj7vLAVOPctMARX0OsgR?= =?us-ascii?Q?zzEahTr7eh315JFQAwVMHhCNCbqLtOPlBnwlgwTJg7J/q6fm2nv/oCGTponM?= =?us-ascii?Q?2f/xnBf6jUDoFZUvA6BrqfDy3xRO81VoT0QqG0FAht0lL5JoNT9gnmr8AdMq?= =?us-ascii?Q?M2QwoYiwFXwUVIoibnCMJSFbVDCC6p/DqWoOsLs6nRnSrnAX+I7snQIdEqEr?= =?us-ascii?Q?hyHP9aCAEChTpdfwufAj9tCvKcw6l95x7GqoXzQWGzvkz+Metw4bprNj10xy?= =?us-ascii?Q?Xun0vBw1mh/jJkqwQJQhzC2VvqFclSP+/McbUxpBcSAu5IvRDGt8DMwL4/Zp?= =?us-ascii?Q?bUucuKc8XpEwZASOqSIwRrKFbUIXKWtIKx0FW/edvUWJlEh/mV7SUNAbGU9F?= =?us-ascii?Q?jI0beD2n9ucj1V/tno3E8vSS7NMX9sBfHI+z0ObQAGAD3m55kfADBnMz/XTA?= =?us-ascii?Q?Obxm/yLtUFwnnIO20ne9Z6oXRfdJ+ZjjMTZ78rnAcFUnqBUzpAN1hjDtoH08?= =?us-ascii?Q?8TotDB8fNVXlhAMnu1/dcNyZxyGqKZufU/ney/mlcSWjL7qfKY4mCsd+gzW/?= =?us-ascii?Q?aYcQAB3Hy11NlUQMEx/4rwXffurcycWiWTHsjfz7pJQncRvRTGhvUrKT7RKz?= =?us-ascii?Q?aFsx2vteS+/yqHRMeciOUSTLwbJAYU8Z0oP5vEdGguewggGj8gsZVl2HbmEn?= =?us-ascii?Q?UUKBbF9MuPKqco6Xv11IGtJCgNJky/Jx+mCpGahZpI3vJeRQRhIKwhLy45pq?= =?us-ascii?Q?UdNfZkAGuhUwufN0Xck=3D?= X-Forefront-Antispam-Report: CIP:84.19.233.75;CTRY:GB;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:edirelay1.ad.cirrus.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(376014)(82310400026)(61400799027)(36860700013);DIR:OUT;SFP:1102; X-OriginatorOrg: opensource.cirrus.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Oct 2025 10:50:27.6167 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: fed726e5-7038-4616-64eb-08de108fa59f X-MS-Exchange-CrossTenant-Id: bec09025-e5bc-40d1-a355-8e955c307de8 X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=bec09025-e5bc-40d1-a355-8e955c307de8;Ip=[84.19.233.75];Helo=[edirelay1.ad.cirrus.com] X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: TreatMessagesAsInternal-BL02EPF0001A0F9.namprd03.prod.outlook.com X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: MW3PR19MB4284 X-Proofpoint-ORIG-GUID: Lsubxj_M_RO5ATTihEaX-iH5eIaw8YTx X-Proofpoint-GUID: Lsubxj_M_RO5ATTihEaX-iH5eIaw8YTx X-Authority-Analysis: v=2.4 cv=bdNmkePB c=1 sm=1 tr=0 ts=68f76577 cx=c_pps a=Yd/70bDpgrqg65f6KmCseQ==:117 a=h1hSm8JtM9GN1ddwPAif2w==:17 a=6eWqkTHjU83fiwn7nKZWdM+Sl24=:19 a=z/mQ4Ysz8XfWz/Q5cLBRGdckG28=:19 a=x6icFKpwvdMA:10 a=s63m1ICgrNkA:10 a=RWc_ulEos4gA:10 a=VkNPw1HP01LnGYTKEx00:22 a=w1d2syhTAAAA:8 a=DhBJ85K0pojyqza_LUEA:9 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMDIxMDA4NSBTYWx0ZWRfX1qSaOFKbT9On UPfYRmXhpFaFB0M98RIqfxIaTQBtr+1UwvZuOlyHKJwcyFljE6U7wQh9rA5VzFDuiy06hacSpJk PQAaB6dV8MFhPyiXuIHXnDNR/BtmMVuo5gfBTtkyWhdOHcNyQe+XWyLfvZhtqiQMFSgDPd+QQkK 8YGbdMlcb9ihcw11Tz41k0B4iPNWJ+eAMAImr1JPethCVy3RHZP8XwH0wA6QsY1Jv6IYc6AsfRC u3tja8rZ4a3Ez5cglEALvX/l+a9ecq653LSHUXI8SWKriLkFAP9hATt3BdO7uT4brMJ04WsUnw5 ZGFsw0RxZF/bM8GLKJv081JWEwmPrKYHJeih2dIgLYcnwdV8ZsoM5cCic+Av658GKZ67skE0SP9 Tfk4LAKWmjccz3bezNLqKMnNhRp4iQ== X-Proofpoint-Spam-Reason: safe Content-Type: text/plain; charset="utf-8" Add a set of test cases for cs_amp_set_efi_calibration_data(). Broadly there are two type of behavior being tested: How the EFI is updated: - Create a new EFI - Overwrite part of existing content - Overwrite part of zero-filled preallocated content - Grow the file to append new content And how the location within the content is chosen: - Overwrite a specific array entry - Overwrite an entry with the same calTarget (silicon ID) - Overwrite a free entry - Append after existing data Plus some cases for error conditions. Signed-off-by: Richard Fitzgerald Reviewed-by: Takashi Iwai --- No changes since V1. include/sound/cs-amp-lib.h | 5 + sound/soc/codecs/cs-amp-lib-test.c | 1399 +++++++++++++++++++++++++++- sound/soc/codecs/cs-amp-lib.c | 1 + 3 files changed, 1397 insertions(+), 8 deletions(-) diff --git a/include/sound/cs-amp-lib.h b/include/sound/cs-amp-lib.h index 240bc53a9307..61e00017c9aa 100644 --- a/include/sound/cs-amp-lib.h +++ b/include/sound/cs-amp-lib.h @@ -71,6 +71,11 @@ struct cs_amp_test_hooks { u32 *returned_attr, unsigned long *size, void *buf); + efi_status_t (*set_efi_variable)(efi_char16_t *name, + efi_guid_t *guid, + u32 attr, + unsigned long size, + void *buf); =20 int (*write_cal_coeff)(struct cs_dsp *dsp, const struct cirrus_amp_cal_controls *controls, diff --git a/sound/soc/codecs/cs-amp-lib-test.c b/sound/soc/codecs/cs-amp-l= ib-test.c index b00ba65badd5..51799a9c86a3 100644 --- a/sound/soc/codecs/cs-amp-lib-test.c +++ b/sound/soc/codecs/cs-amp-lib-test.c @@ -19,6 +19,10 @@ #include #include =20 +#define CIRRUS_LOGIC_CALIBRATION_EFI_NAME L"CirrusSmartAmpCalibrationData" +#define CIRRUS_LOGIC_CALIBRATION_EFI_GUID \ + EFI_GUID(0x02f9af02, 0x7734, 0x4233, 0xb4, 0x3d, 0x93, 0xfe, 0x5a, 0xa3, = 0x5d, 0xb3) + #define LENOVO_SPEAKER_ID_EFI_NAME L"SdwSpeaker" #define LENOVO_SPEAKER_ID_EFI_GUID \ EFI_GUID(0x48df970e, 0xe27f, 0x460a, 0xb5, 0x86, 0x77, 0x19, 0x80, 0x1d, = 0x92, 0x82) @@ -27,6 +31,10 @@ #define HP_SPEAKER_ID_EFI_GUID \ EFI_GUID(0xc49593a4, 0xd099, 0x419b, 0xa2, 0xc3, 0x67, 0xe9, 0x80, 0xe6, = 0x1d, 0x1e) =20 +#define HP_CALIBRATION_EFI_NAME L"SmartAmpCalibrationData" +#define HP_CALIBRATION_EFI_GUID \ + EFI_GUID(0x53559579, 0x8753, 0x4f5c, 0x91, 0x30, 0xe8, 0x2a, 0xcf, 0xb8, = 0xd8, 0x93) + KUNIT_DEFINE_ACTION_WRAPPER(faux_device_destroy_wrapper, faux_device_destr= oy, struct faux_device *) =20 @@ -35,6 +43,7 @@ struct cs_amp_lib_test_priv { =20 struct cirrus_amp_efi_data *cal_blob; struct list_head ctl_write_list; + u32 efi_attr; }; =20 struct cs_amp_lib_test_ctl_write_entry { @@ -48,6 +57,20 @@ struct cs_amp_lib_test_param { int amp_index; }; =20 +static struct cirrus_amp_efi_data *cs_amp_lib_test_cal_blob_dup(struct kun= it *test) +{ + struct cs_amp_lib_test_priv *priv =3D test->priv; + struct cirrus_amp_efi_data *temp; + + KUNIT_ASSERT_EQ(test, struct_size(priv->cal_blob, data, priv->cal_blob->c= ount), + priv->cal_blob->size); + temp =3D kunit_kmalloc(test, priv->cal_blob->size, GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, temp); + memcpy(temp, priv->cal_blob, priv->cal_blob->size); + + return temp; +} + static void cs_amp_lib_test_init_dummy_cal_blob(struct kunit *test, int nu= m_amps) { struct cs_amp_lib_test_priv *priv =3D test->priv; @@ -68,9 +91,15 @@ static void cs_amp_lib_test_init_dummy_cal_blob(struct k= unit *test, int num_amps for (i =3D 0; i < num_amps; i++) priv->cal_blob->data[i].calTime[0] |=3D 1; =20 - /* Ensure that all UIDs are non-zero and unique. */ - for (i =3D 0; i < num_amps; i++) + /* + * Ensure that all UIDs are non-zero and unique. + * Make both words non-zero and not equal values, so that + * tests can verify that both words were checked or changed. + */ + for (i =3D 0; i < num_amps; i++) { *(u8 *)&priv->cal_blob->data[i].calTarget[0] =3D i + 1; + *(u8 *)&priv->cal_blob->data[i].calTarget[1] =3D i; + } } =20 static u64 cs_amp_lib_test_get_target_uid(struct kunit *test) @@ -198,9 +227,8 @@ static efi_status_t cs_amp_lib_test_get_efi_variable(ef= i_char16_t *name, unsigned long *size, void *buf) { - static const efi_char16_t expected_name[] =3D L"CirrusSmartAmpCalibration= Data"; - static const efi_guid_t expected_guid =3D - EFI_GUID(0x02f9af02, 0x7734, 0x4233, 0xb4, 0x3d, 0x93, 0xfe, 0x5a, 0xa3,= 0x5d, 0xb3); + static const efi_char16_t expected_name[] =3D CIRRUS_LOGIC_CALIBRATION_EF= I_NAME; + static const efi_guid_t expected_guid =3D CIRRUS_LOGIC_CALIBRATION_EFI_GU= ID; struct kunit *test =3D kunit_get_current_test(); struct cs_amp_lib_test_priv *priv =3D test->priv; =20 @@ -222,9 +250,56 @@ static efi_status_t cs_amp_lib_test_get_efi_variable(e= fi_char16_t *name, memcpy(buf, priv->cal_blob, priv->cal_blob->size); =20 if (returned_attr) { - *returned_attr =3D EFI_VARIABLE_NON_VOLATILE | - EFI_VARIABLE_BOOTSERVICE_ACCESS | - EFI_VARIABLE_RUNTIME_ACCESS; + if (priv->efi_attr) + *returned_attr =3D priv->efi_attr; + else + *returned_attr =3D EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS; + } + + return EFI_SUCCESS; +} + +#define CS_AMP_LIB_ZERO_FILLED_BLOB_SIZE \ + struct_size_t(struct cirrus_amp_efi_data, data, 8) + +/* Redirected get_efi_variable to simulate reading a prealloced zero-fille= d blob */ +static efi_status_t cs_amp_lib_test_get_efi_variable_all_zeros(efi_char16_= t *name, + efi_guid_t *guid, + u32 *returned_attr, + unsigned long *size, + void *buf) +{ + static const efi_char16_t expected_name[] =3D CIRRUS_LOGIC_CALIBRATION_EF= I_NAME; + static const efi_guid_t expected_guid =3D CIRRUS_LOGIC_CALIBRATION_EFI_GU= ID; + struct kunit *test =3D kunit_get_current_test(); + struct cs_amp_lib_test_priv *priv =3D test->priv; + + KUNIT_EXPECT_NOT_ERR_OR_NULL(test, name); + KUNIT_EXPECT_NOT_ERR_OR_NULL(test, guid); + + if (memcmp(name, expected_name, sizeof(expected_name)) || + efi_guidcmp(*guid, expected_guid)) + return -EFI_NOT_FOUND; + + if (!buf) { + *size =3D CS_AMP_LIB_ZERO_FILLED_BLOB_SIZE; + return EFI_BUFFER_TOO_SMALL; + } + + KUNIT_ASSERT_EQ(test, *size, struct_size(priv->cal_blob, data, 8)); + priv->cal_blob =3D kunit_kzalloc(test, CS_AMP_LIB_ZERO_FILLED_BLOB_SIZE, = GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, priv->cal_blob); + memset(buf, 0, CS_AMP_LIB_ZERO_FILLED_BLOB_SIZE); + + if (returned_attr) { + if (priv->efi_attr) + *returned_attr =3D priv->efi_attr; + else + *returned_attr =3D EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS; } =20 return EFI_SUCCESS; @@ -789,6 +864,1292 @@ static void cs_amp_lib_test_write_ambient_test(struc= t kunit *test) KUNIT_EXPECT_EQ(test, entry->value, 18); } =20 +static efi_status_t cs_amp_lib_test_set_efi_variable(efi_char16_t *name, + efi_guid_t *guid, + u32 attr, + unsigned long size, + void *buf) +{ + static const efi_char16_t expected_name[] =3D CIRRUS_LOGIC_CALIBRATION_EF= I_NAME; + static const efi_guid_t expected_guid =3D CIRRUS_LOGIC_CALIBRATION_EFI_GU= ID; + struct kunit *test =3D kunit_get_current_test(); + struct cs_amp_lib_test_priv *priv =3D test->priv; + + KUNIT_ASSERT_NOT_NULL(test, name); + KUNIT_ASSERT_NOT_NULL(test, guid); + + if (memcmp(name, expected_name, sizeof(expected_name)) || + efi_guidcmp(*guid, expected_guid)) + return -EFI_NOT_FOUND; + + KUNIT_ASSERT_NOT_NULL(test, buf); + KUNIT_ASSERT_NE(test, 0, size); + + kunit_kfree(test, priv->cal_blob); + priv->cal_blob =3D kunit_kmalloc(test, size, GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, priv->cal_blob); + memcpy(priv->cal_blob, buf, size); + priv->efi_attr =3D attr; + + return EFI_SUCCESS; +} + +static efi_status_t cs_amp_lib_test_set_efi_variable_denied(efi_char16_t *= name, + efi_guid_t *guid, + u32 attr, + unsigned long size, + void *buf) +{ + return EFI_WRITE_PROTECTED; +} + +#define CS_AMP_CAL_DEFAULT_EFI_ATTR \ + (EFI_VARIABLE_NON_VOLATILE | \ + EFI_VARIABLE_BOOTSERVICE_ACCESS | \ + EFI_VARIABLE_RUNTIME_ACCESS) + +static void cs_amp_lib_test_create_new_cal_efi(struct kunit *test) +{ + struct cs_amp_lib_test_priv *priv =3D test->priv; + struct device *dev =3D &priv->amp_dev->dev; + struct cirrus_amp_cal_data data; + int i; + + kunit_activate_static_stub(test, + cs_amp_test_hooks->get_efi_variable, + cs_amp_lib_test_get_efi_variable_none); + kunit_activate_static_stub(test, + cs_amp_test_hooks->set_efi_variable, + cs_amp_lib_test_set_efi_variable); + + /* For unspecified number of amps */ + get_random_bytes(&data, sizeof(data)); + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, -1, -1, &da= ta)); + KUNIT_EXPECT_EQ(test, CS_AMP_CAL_DEFAULT_EFI_ATTR, priv->efi_attr); + KUNIT_EXPECT_GE(test, priv->cal_blob->count, 1); + KUNIT_EXPECT_LE(test, priv->cal_blob->count, 8); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, priv->cal_blob->c= ount), + priv->cal_blob->size); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[0], sizeof(data)); + for (i =3D 1; i < priv->cal_blob->count; i++) + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[i], sizeof(dat= a))); + + /* For 2 amps */ + priv->cal_blob =3D NULL; + get_random_bytes(&data, sizeof(data)); + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, -1, 2, &dat= a)); + KUNIT_EXPECT_EQ(test, CS_AMP_CAL_DEFAULT_EFI_ATTR, priv->efi_attr); + KUNIT_EXPECT_EQ(test, 2, priv->cal_blob->count); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, 2), priv->cal_blo= b->size); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[0], sizeof(data)); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[1], sizeof(data= ))); + + /* For 4 amps */ + priv->cal_blob =3D NULL; + get_random_bytes(&data, sizeof(data)); + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, -1, 4, &dat= a)); + KUNIT_EXPECT_EQ(test, 4, priv->cal_blob->count); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, 4), priv->cal_blo= b->size); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[0], sizeof(data)); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[1], sizeof(data= ))); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[2], sizeof(data= ))); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[3], sizeof(data= ))); + + /* For 6 amps */ + priv->cal_blob =3D NULL; + get_random_bytes(&data, sizeof(data)); + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, -1, 6, &dat= a)); + KUNIT_EXPECT_EQ(test, 6, priv->cal_blob->count); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, 6), priv->cal_blo= b->size); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[0], sizeof(data)); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[1], sizeof(data= ))); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[2], sizeof(data= ))); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[3], sizeof(data= ))); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[4], sizeof(data= ))); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[5], sizeof(data= ))); +} + +static void cs_amp_lib_test_create_new_cal_efi_indexed(struct kunit *test) +{ + struct cs_amp_lib_test_priv *priv =3D test->priv; + struct device *dev =3D &priv->amp_dev->dev; + struct cirrus_amp_cal_data data; + + kunit_activate_static_stub(test, + cs_amp_test_hooks->get_efi_variable, + cs_amp_lib_test_get_efi_variable_none); + kunit_activate_static_stub(test, + cs_amp_test_hooks->set_efi_variable, + cs_amp_lib_test_set_efi_variable); + + /* In slot 0 */ + priv->cal_blob =3D NULL; + get_random_bytes(&data, sizeof(data)); + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, 0, 6, &data= )); + KUNIT_EXPECT_EQ(test, 6, priv->cal_blob->count); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, 6), priv->cal_blo= b->size); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[0], sizeof(data)); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[1], sizeof(data= ))); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[2], sizeof(data= ))); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[3], sizeof(data= ))); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[4], sizeof(data= ))); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[5], sizeof(data= ))); + + /* In slot 1 */ + priv->cal_blob =3D NULL; + get_random_bytes(&data, sizeof(data)); + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, 1, 6, &data= )); + KUNIT_EXPECT_EQ(test, 6, priv->cal_blob->count); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, 6), priv->cal_blo= b->size); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[1], sizeof(data)); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[0], sizeof(data= ))); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[2], sizeof(data= ))); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[3], sizeof(data= ))); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[4], sizeof(data= ))); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[5], sizeof(data= ))); + + /* In slot 5 */ + priv->cal_blob =3D NULL; + get_random_bytes(&data, sizeof(data)); + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, 5, 6, &data= )); + KUNIT_EXPECT_EQ(test, 6, priv->cal_blob->count); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, 6), priv->cal_blo= b->size); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[5], sizeof(data)); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[0], sizeof(data= ))); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[1], sizeof(data= ))); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[2], sizeof(data= ))); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[3], sizeof(data= ))); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[4], sizeof(data= ))); +} + +static void cs_amp_lib_test_create_new_cal_efi_indexed_no_max(struct kunit= *test) +{ + struct cs_amp_lib_test_priv *priv =3D test->priv; + struct device *dev =3D &priv->amp_dev->dev; + struct cirrus_amp_cal_data data; + int i; + + kunit_activate_static_stub(test, + cs_amp_test_hooks->get_efi_variable, + cs_amp_lib_test_get_efi_variable_none); + kunit_activate_static_stub(test, + cs_amp_test_hooks->set_efi_variable, + cs_amp_lib_test_set_efi_variable); + + /* In slot 0 with unspecified number of amps */ + priv->cal_blob =3D NULL; + get_random_bytes(&data, sizeof(data)); + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, 0, -1, &dat= a)); + KUNIT_EXPECT_GE(test, priv->cal_blob->count, 1); + KUNIT_EXPECT_LE(test, priv->cal_blob->count, 8); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, priv->cal_blob->c= ount), + priv->cal_blob->size); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[0], sizeof(data)); + for (i =3D 1; i < priv->cal_blob->count; i++) + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[i], sizeof(dat= a))); + + /* In slot 1 with unspecified number of amps */ + priv->cal_blob =3D NULL; + get_random_bytes(&data, sizeof(data)); + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, 1, -1, &dat= a)); + KUNIT_EXPECT_GE(test, priv->cal_blob->count, 2); + KUNIT_EXPECT_LE(test, priv->cal_blob->count, 8); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, priv->cal_blob->c= ount), + priv->cal_blob->size); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[1], sizeof(data)); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[0], sizeof(data= ))); + for (i =3D 2; i < priv->cal_blob->count; i++) + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[i], sizeof(dat= a))); + + /* In slot 5 with unspecified number of amps */ + priv->cal_blob =3D NULL; + get_random_bytes(&data, sizeof(data)); + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, 5, -1, &dat= a)); + KUNIT_EXPECT_GE(test, priv->cal_blob->count, 6); + KUNIT_EXPECT_LE(test, priv->cal_blob->count, 8); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, priv->cal_blob->c= ount), + priv->cal_blob->size); + for (i =3D 0; (i < 5) && (i < priv->cal_blob->count); i++) + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[i], sizeof(dat= a))); + + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[5], sizeof(data)); + for (i =3D 6; i < priv->cal_blob->count; i++) + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[i], sizeof(dat= a))); +} + +static void cs_amp_lib_test_grow_append_cal_efi(struct kunit *test) +{ + struct cs_amp_lib_test_priv *priv =3D test->priv; + struct device *dev =3D &priv->amp_dev->dev; + const struct cirrus_amp_efi_data *original_blob; + struct cirrus_amp_cal_data data; + + kunit_activate_static_stub(test, + cs_amp_test_hooks->get_efi_variable, + cs_amp_lib_test_get_efi_variable); + kunit_activate_static_stub(test, + cs_amp_test_hooks->set_efi_variable, + cs_amp_lib_test_set_efi_variable); + + /* Initially 1 used entry grown to 2 entries */ + cs_amp_lib_test_init_dummy_cal_blob(test, 1); + KUNIT_ASSERT_EQ(test, 1, priv->cal_blob->count); + original_blob =3D cs_amp_lib_test_cal_blob_dup(test); + get_random_bytes(&data, sizeof(data)); + data.calTarget[0] =3D 0xaaaaaaaa; /* won't match */ + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, -1, 2, &dat= a)); + KUNIT_EXPECT_EQ(test, CS_AMP_CAL_DEFAULT_EFI_ATTR, priv->efi_attr); + KUNIT_EXPECT_EQ(test, 2, priv->cal_blob->count); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, 2), priv->cal_blo= b->size); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[0], &priv->cal_blob->data[0= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[1], sizeof(data)); + + /* Initially 1 entry grown to 4 entries */ + priv->cal_blob =3D NULL; + cs_amp_lib_test_init_dummy_cal_blob(test, 1); + KUNIT_ASSERT_EQ(test, 1, priv->cal_blob->count); + original_blob =3D cs_amp_lib_test_cal_blob_dup(test); + get_random_bytes(&data, sizeof(data)); + data.calTarget[0] =3D 0xaaaaaaaa; /* won't match */ + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, -1, 4, &dat= a)); + KUNIT_EXPECT_EQ(test, 4, priv->cal_blob->count); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, 4), priv->cal_blo= b->size); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[0], &priv->cal_blob->data[0= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[1], sizeof(data)); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[2], sizeof(data= ))); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[3], sizeof(data= ))); + + /* Initially 2 entries grown to 4 entries */ + priv->cal_blob =3D NULL; + cs_amp_lib_test_init_dummy_cal_blob(test, 2); + KUNIT_ASSERT_EQ(test, 2, priv->cal_blob->count); + original_blob =3D cs_amp_lib_test_cal_blob_dup(test); + get_random_bytes(&data, sizeof(data)); + data.calTarget[0] =3D 0xaaaaaaaa; /* won't match */ + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, -1, 4, &dat= a)); + KUNIT_EXPECT_EQ(test, 4, priv->cal_blob->count); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, 4), priv->cal_blo= b->size); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[0], &priv->cal_blob->data[0= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[1], &priv->cal_blob->data[1= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[2], sizeof(data)); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[3], sizeof(data= ))); + + /* Initially 1 entry grown to 6 entries */ + priv->cal_blob =3D NULL; + cs_amp_lib_test_init_dummy_cal_blob(test, 1); + KUNIT_ASSERT_EQ(test, 1, priv->cal_blob->count); + original_blob =3D cs_amp_lib_test_cal_blob_dup(test); + get_random_bytes(&data, sizeof(data)); + data.calTarget[0] =3D 0xaaaaaaaa; /* won't match */ + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, -1, 6, &dat= a)); + KUNIT_EXPECT_EQ(test, 6, priv->cal_blob->count); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, 6), priv->cal_blo= b->size); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[0], &priv->cal_blob->data[0= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[1], sizeof(data)); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[2], sizeof(data= ))); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[3], sizeof(data= ))); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[4], sizeof(data= ))); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[5], sizeof(data= ))); + + /* Initially 4 entries grown to 6 entries */ + priv->cal_blob =3D NULL; + cs_amp_lib_test_init_dummy_cal_blob(test, 4); + KUNIT_ASSERT_EQ(test, 4, priv->cal_blob->count); + original_blob =3D cs_amp_lib_test_cal_blob_dup(test); + get_random_bytes(&data, sizeof(data)); + data.calTarget[0] =3D 0xaaaaaaaa; /* won't match */ + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, -1, 6, &dat= a)); + KUNIT_EXPECT_EQ(test, 6, priv->cal_blob->count); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, 6), priv->cal_blo= b->size); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[0], &priv->cal_blob->data[0= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[1], &priv->cal_blob->data[1= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[2], &priv->cal_blob->data[2= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[3], &priv->cal_blob->data[3= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[4], sizeof(data)); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[5], sizeof(data= ))); +} + +static void cs_amp_lib_test_grow_append_cal_efi_indexed(struct kunit *test) +{ + struct cs_amp_lib_test_priv *priv =3D test->priv; + struct device *dev =3D &priv->amp_dev->dev; + const struct cirrus_amp_efi_data *original_blob; + struct cirrus_amp_cal_data data; + + kunit_activate_static_stub(test, + cs_amp_test_hooks->get_efi_variable, + cs_amp_lib_test_get_efi_variable); + kunit_activate_static_stub(test, + cs_amp_test_hooks->set_efi_variable, + cs_amp_lib_test_set_efi_variable); + + /* Initially 1 entry grown to 2 entries using slot 1 */ + priv->cal_blob =3D NULL; + cs_amp_lib_test_init_dummy_cal_blob(test, 1); + KUNIT_ASSERT_EQ(test, 1, priv->cal_blob->count); + original_blob =3D cs_amp_lib_test_cal_blob_dup(test); + get_random_bytes(&data, sizeof(data)); + data.calTarget[0] =3D 0xaaaaaaaa; /* won't match */ + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, 1, 2, &data= )); + KUNIT_EXPECT_EQ(test, 2, priv->cal_blob->count); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, 2), priv->cal_blo= b->size); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[0], &priv->cal_blob->data[0= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[1], sizeof(data)); + + /* Initially 1 entry grown to 6 entries using slot 1 */ + priv->cal_blob =3D NULL; + cs_amp_lib_test_init_dummy_cal_blob(test, 1); + KUNIT_ASSERT_EQ(test, 1, priv->cal_blob->count); + original_blob =3D cs_amp_lib_test_cal_blob_dup(test); + get_random_bytes(&data, sizeof(data)); + data.calTarget[0] =3D 0xaaaaaaaa; /* won't match */ + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, 1, 6, &data= )); + KUNIT_EXPECT_EQ(test, 6, priv->cal_blob->count); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, 6), priv->cal_blo= b->size); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[0], &priv->cal_blob->data[0= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[1], sizeof(data)); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[2], sizeof(data= ))); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[3], sizeof(data= ))); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[4], sizeof(data= ))); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[5], sizeof(data= ))); + + /* Initially 2 entries grown to 6 entries using slot 2 */ + priv->cal_blob =3D NULL; + cs_amp_lib_test_init_dummy_cal_blob(test, 2); + KUNIT_ASSERT_EQ(test, 2, priv->cal_blob->count); + original_blob =3D cs_amp_lib_test_cal_blob_dup(test); + get_random_bytes(&data, sizeof(data)); + data.calTarget[0] =3D 0xaaaaaaaa; /* won't match */ + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, 2, 6, &data= )); + KUNIT_EXPECT_EQ(test, 6, priv->cal_blob->count); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, 6), priv->cal_blo= b->size); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[0], &priv->cal_blob->data[0= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[1], &priv->cal_blob->data[1= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[2], sizeof(data)); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[3], sizeof(data= ))); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[4], sizeof(data= ))); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[5], sizeof(data= ))); + + /* Initially 2 entries grown to 6 entries using slot 4 */ + kunit_kfree(test, original_blob); + kunit_kfree(test, priv->cal_blob); + priv->cal_blob =3D NULL; + cs_amp_lib_test_init_dummy_cal_blob(test, 2); + KUNIT_ASSERT_EQ(test, 2, priv->cal_blob->count); + original_blob =3D cs_amp_lib_test_cal_blob_dup(test); + get_random_bytes(&data, sizeof(data)); + data.calTarget[0] =3D 0xaaaaaaaa; /* won't match */ + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, 4, 6, &data= )); + KUNIT_EXPECT_EQ(test, 6, priv->cal_blob->count); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, 6), priv->cal_blo= b->size); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[0], &priv->cal_blob->data[0= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[1], &priv->cal_blob->data[1= ], sizeof(data)); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[2], sizeof(data= ))); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[3], sizeof(data= ))); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[4], sizeof(data)); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[5], sizeof(data= ))); +} + +static void cs_amp_lib_test_cal_efi_all_zeros_add_first(struct kunit *test) +{ + struct cs_amp_lib_test_priv *priv =3D test->priv; + struct device *dev =3D &priv->amp_dev->dev; + struct cirrus_amp_cal_data data; + int i; + + /* Simulate a BIOS reserving EFI space that is entirely zero-filled. */ + kunit_activate_static_stub(test, + cs_amp_test_hooks->get_efi_variable, + cs_amp_lib_test_get_efi_variable_all_zeros); + kunit_activate_static_stub(test, + cs_amp_test_hooks->set_efi_variable, + cs_amp_lib_test_set_efi_variable); + + /* + * Add an entry. The header should be filled in to match the + * original EFI variable size. + */ + get_random_bytes(&data, sizeof(data)); + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, -1, -1, &da= ta)); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, 8), priv->cal_blo= b->size); + KUNIT_EXPECT_EQ(test, 8, priv->cal_blob->count); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[0], sizeof(data)); + for (i =3D 1; i < priv->cal_blob->count; i++) { + KUNIT_EXPECT_EQ(test, 0, priv->cal_blob->data[i].calTime[0]); + KUNIT_EXPECT_EQ(test, 0, priv->cal_blob->data[i].calTime[1]); + } +} + +static void cs_amp_lib_test_cal_efi_all_zeros_add_first_no_shrink(struct k= unit *test) +{ + struct cs_amp_lib_test_priv *priv =3D test->priv; + struct device *dev =3D &priv->amp_dev->dev; + struct cirrus_amp_cal_data data; + int i; + + /* Simulate a BIOS reserving EFI space that is entirely zero-filled. */ + kunit_activate_static_stub(test, + cs_amp_test_hooks->get_efi_variable, + cs_amp_lib_test_get_efi_variable_all_zeros); + kunit_activate_static_stub(test, + cs_amp_test_hooks->set_efi_variable, + cs_amp_lib_test_set_efi_variable); + + /* + * Add an entry. The header should be filled in to match the + * original EFI variable size. A number of amps less than the + * available preallocated space does not shrink the EFI variable. + */ + get_random_bytes(&data, sizeof(data)); + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, -1, 4, &dat= a)); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, 8), priv->cal_blo= b->size); + KUNIT_EXPECT_EQ(test, 8, priv->cal_blob->count); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[0], sizeof(data)); + for (i =3D 1; i < priv->cal_blob->count; i++) { + KUNIT_EXPECT_EQ(test, 0, priv->cal_blob->data[i].calTime[0]); + KUNIT_EXPECT_EQ(test, 0, priv->cal_blob->data[i].calTime[1]); + } +} + +static void cs_amp_lib_test_cal_efi_all_zeros_add_first_indexed(struct kun= it *test) +{ + struct cs_amp_lib_test_priv *priv =3D test->priv; + struct device *dev =3D &priv->amp_dev->dev; + struct cirrus_amp_cal_data data; + int i; + + /* Simulate a BIOS reserving EFI space that is entirely zero-filled. */ + kunit_activate_static_stub(test, + cs_amp_test_hooks->get_efi_variable, + cs_amp_lib_test_get_efi_variable_all_zeros); + kunit_activate_static_stub(test, + cs_amp_test_hooks->set_efi_variable, + cs_amp_lib_test_set_efi_variable); + + /* + * Write entry to slot 2. The header should be filled in to match + * the original EFI variable size. + */ + get_random_bytes(&data, sizeof(data)); + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, 2, -1, &dat= a)); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, 8), priv->cal_blo= b->size); + KUNIT_EXPECT_EQ(test, 8, priv->cal_blob->count); + KUNIT_EXPECT_EQ(test, 0, priv->cal_blob->data[0].calTime[0]); + KUNIT_EXPECT_EQ(test, 0, priv->cal_blob->data[0].calTime[1]); + KUNIT_EXPECT_EQ(test, 0, priv->cal_blob->data[1].calTime[0]); + KUNIT_EXPECT_EQ(test, 0, priv->cal_blob->data[1].calTime[1]); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[2], sizeof(data)); + for (i =3D 3; i < priv->cal_blob->count; i++) { + KUNIT_EXPECT_EQ(test, 0, priv->cal_blob->data[i].calTime[0]); + KUNIT_EXPECT_EQ(test, 0, priv->cal_blob->data[i].calTime[1]); + } +} + +static void cs_amp_lib_test_cal_efi_all_zeros_add_first_indexed_no_shrink(= struct kunit *test) +{ + struct cs_amp_lib_test_priv *priv =3D test->priv; + struct device *dev =3D &priv->amp_dev->dev; + struct cirrus_amp_cal_data data; + int i; + + /* Simulate a BIOS reserving EFI space that is entirely zero-filled. */ + kunit_activate_static_stub(test, + cs_amp_test_hooks->get_efi_variable, + cs_amp_lib_test_get_efi_variable_all_zeros); + kunit_activate_static_stub(test, + cs_amp_test_hooks->set_efi_variable, + cs_amp_lib_test_set_efi_variable); + + /* + * Write entry to slot 2. The header should be filled in to match + * the original EFI variable size. A number of amps less than the + * available preallocated space does not shrink the EFI variable. + */ + get_random_bytes(&data, sizeof(data)); + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, 2, 4, &data= )); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, 8), priv->cal_blo= b->size); + KUNIT_EXPECT_EQ(test, 8, priv->cal_blob->count); + KUNIT_EXPECT_EQ(test, 0, priv->cal_blob->data[0].calTime[0]); + KUNIT_EXPECT_EQ(test, 0, priv->cal_blob->data[0].calTime[1]); + KUNIT_EXPECT_EQ(test, 0, priv->cal_blob->data[1].calTime[0]); + KUNIT_EXPECT_EQ(test, 0, priv->cal_blob->data[1].calTime[1]); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[2], sizeof(data)); + for (i =3D 3; i < priv->cal_blob->count; i++) { + KUNIT_EXPECT_EQ(test, 0, priv->cal_blob->data[i].calTime[0]); + KUNIT_EXPECT_EQ(test, 0, priv->cal_blob->data[i].calTime[1]); + } +} + +static void cs_amp_lib_test_grow_append_cal_efi_indexed_no_max(struct kuni= t *test) +{ + struct cs_amp_lib_test_priv *priv =3D test->priv; + struct device *dev =3D &priv->amp_dev->dev; + const struct cirrus_amp_efi_data *original_blob; + struct cirrus_amp_cal_data data; + int i; + + kunit_activate_static_stub(test, + cs_amp_test_hooks->get_efi_variable, + cs_amp_lib_test_get_efi_variable); + kunit_activate_static_stub(test, + cs_amp_test_hooks->set_efi_variable, + cs_amp_lib_test_set_efi_variable); + + /* Initially 1 entry adding slot 1 */ + cs_amp_lib_test_init_dummy_cal_blob(test, 1); + KUNIT_ASSERT_EQ(test, 1, priv->cal_blob->count); + original_blob =3D cs_amp_lib_test_cal_blob_dup(test); + get_random_bytes(&data, sizeof(data)); + data.calTarget[0] =3D 0xaaaaaaaa; /* won't match */ + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, 1, -1, &dat= a)); + KUNIT_EXPECT_GE(test, priv->cal_blob->count, 2); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, priv->cal_blob->c= ount), + priv->cal_blob->size); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[0], &priv->cal_blob->data[0= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[1], sizeof(data)); + for (i =3D 2; i < priv->cal_blob->count; i++) + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[i], sizeof(dat= a))); + + /* Initially 1 entry adding slot 3 */ + cs_amp_lib_test_init_dummy_cal_blob(test, 1); + KUNIT_ASSERT_EQ(test, 1, priv->cal_blob->count); + original_blob =3D cs_amp_lib_test_cal_blob_dup(test); + get_random_bytes(&data, sizeof(data)); + data.calTarget[0] =3D 0xaaaaaaaa; /* won't match */ + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, 3, -1, &dat= a)); + KUNIT_EXPECT_GE(test, priv->cal_blob->count, 4); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, priv->cal_blob->c= ount), + priv->cal_blob->size); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[0], &priv->cal_blob->data[0= ], sizeof(data)); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[1], sizeof(data= ))); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[2], sizeof(data= ))); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[3], sizeof(data)); + for (i =3D 4; i < priv->cal_blob->count; i++) + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[i], sizeof(dat= a))); + + /* Initially 2 entries adding slot 3 */ + priv->cal_blob =3D NULL; + cs_amp_lib_test_init_dummy_cal_blob(test, 2); + KUNIT_ASSERT_EQ(test, 2, priv->cal_blob->count); + original_blob =3D cs_amp_lib_test_cal_blob_dup(test); + get_random_bytes(&data, sizeof(data)); + data.calTarget[0] =3D 0xaaaaaaaa; /* won't match */ + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, 3, -1, &dat= a)); + KUNIT_EXPECT_GE(test, priv->cal_blob->count, 1); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, priv->cal_blob->c= ount), + priv->cal_blob->size); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[0], &priv->cal_blob->data[0= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[1], &priv->cal_blob->data[1= ], sizeof(data)); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[2], sizeof(data= ))); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[3], sizeof(data)); + for (i =3D 4; i < priv->cal_blob->count; i++) + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[i], sizeof(dat= a))); + + /* Initially 4 entries adding slot 4 */ + priv->cal_blob =3D NULL; + cs_amp_lib_test_init_dummy_cal_blob(test, 4); + KUNIT_ASSERT_EQ(test, 4, priv->cal_blob->count); + original_blob =3D cs_amp_lib_test_cal_blob_dup(test); + get_random_bytes(&data, sizeof(data)); + data.calTarget[0] =3D 0xaaaaaaaa; /* won't match */ + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, 4, -1, &dat= a)); + KUNIT_EXPECT_GE(test, priv->cal_blob->count, 1); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, priv->cal_blob->c= ount), + priv->cal_blob->size); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[0], &priv->cal_blob->data[0= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[1], &priv->cal_blob->data[1= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[2], &priv->cal_blob->data[2= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[3], &priv->cal_blob->data[3= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[4], sizeof(data)); + for (i =3D 5; i < priv->cal_blob->count; i++) + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[i], sizeof(dat= a))); + + /* Initially 4 entries adding slot 6 */ + priv->cal_blob =3D NULL; + cs_amp_lib_test_init_dummy_cal_blob(test, 4); + KUNIT_ASSERT_EQ(test, 4, priv->cal_blob->count); + original_blob =3D cs_amp_lib_test_cal_blob_dup(test); + get_random_bytes(&data, sizeof(data)); + data.calTarget[0] =3D 0xaaaaaaaa; /* won't match */ + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, 6, -1, &dat= a)); + KUNIT_EXPECT_GE(test, priv->cal_blob->count, 1); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, priv->cal_blob->c= ount), + priv->cal_blob->size); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[0], &priv->cal_blob->data[0= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[1], &priv->cal_blob->data[1= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[2], &priv->cal_blob->data[2= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[3], &priv->cal_blob->data[3= ], sizeof(data)); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[4], sizeof(data= ))); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[5], sizeof(data= ))); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[6], sizeof(data)); + for (i =3D 7; i < priv->cal_blob->count; i++) + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[i], sizeof(dat= a))); +} + +static void cs_amp_lib_test_grow_cal_efi_replace_indexed(struct kunit *tes= t) +{ + struct cs_amp_lib_test_priv *priv =3D test->priv; + struct device *dev =3D &priv->amp_dev->dev; + const struct cirrus_amp_efi_data *original_blob; + struct cirrus_amp_cal_data data; + + kunit_activate_static_stub(test, + cs_amp_test_hooks->get_efi_variable, + cs_amp_lib_test_get_efi_variable); + kunit_activate_static_stub(test, + cs_amp_test_hooks->set_efi_variable, + cs_amp_lib_test_set_efi_variable); + + /* Initially 1 entry grown to 2 entries overwriting slot 0 */ + cs_amp_lib_test_init_dummy_cal_blob(test, 1); + KUNIT_ASSERT_EQ(test, 1, priv->cal_blob->count); + original_blob =3D cs_amp_lib_test_cal_blob_dup(test); + get_random_bytes(&data, sizeof(data)); + data.calTarget[0] =3D 0xaaaaaaaa; /* won't match */ + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, 0, 2, &data= )); + KUNIT_EXPECT_EQ(test, 2, priv->cal_blob->count); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, 2), priv->cal_blo= b->size); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[0], sizeof(data)); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[1], sizeof(data= ))); + + /* Initially 2 entries grown to 4 entries overwriting slot 1 */ + priv->cal_blob =3D NULL; + cs_amp_lib_test_init_dummy_cal_blob(test, 2); + KUNIT_ASSERT_EQ(test, 2, priv->cal_blob->count); + original_blob =3D cs_amp_lib_test_cal_blob_dup(test); + get_random_bytes(&data, sizeof(data)); + data.calTarget[0] =3D 0xaaaaaaaa; /* won't match */ + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, 1, 4, &data= )); + KUNIT_EXPECT_EQ(test, 4, priv->cal_blob->count); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, 4), priv->cal_blo= b->size); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[0], &priv->cal_blob->data[0= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[1], sizeof(data)); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[2], sizeof(data= ))); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[3], sizeof(data= ))); + + /* Initially 4 entries grown to 6 entries overwriting slot 1 */ + priv->cal_blob =3D NULL; + cs_amp_lib_test_init_dummy_cal_blob(test, 4); + KUNIT_ASSERT_EQ(test, 4, priv->cal_blob->count); + original_blob =3D cs_amp_lib_test_cal_blob_dup(test); + get_random_bytes(&data, sizeof(data)); + data.calTarget[0] =3D 0xaaaaaaaa; /* won't match */ + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, 1, 6, &data= )); + KUNIT_EXPECT_EQ(test, 6, priv->cal_blob->count); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, 6), priv->cal_blo= b->size); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[0], &priv->cal_blob->data[0= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[1], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[2], &priv->cal_blob->data[2= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[3], &priv->cal_blob->data[3= ], sizeof(data)); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[4], sizeof(data= ))); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[5], sizeof(data= ))); + + /* Initially 4 entries grown to 6 entries overwriting slot 3 */ + priv->cal_blob =3D NULL; + cs_amp_lib_test_init_dummy_cal_blob(test, 4); + KUNIT_ASSERT_EQ(test, 4, priv->cal_blob->count); + original_blob =3D cs_amp_lib_test_cal_blob_dup(test); + get_random_bytes(&data, sizeof(data)); + data.calTarget[0] =3D 0xaaaaaaaa; /* won't match */ + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, 3, 6, &data= )); + KUNIT_EXPECT_EQ(test, 6, priv->cal_blob->count); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, 6), priv->cal_blo= b->size); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[0], &priv->cal_blob->data[0= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[1], &priv->cal_blob->data[1= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[2], &priv->cal_blob->data[2= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[3], sizeof(data)); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[4], sizeof(data= ))); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[5], sizeof(data= ))); + + /* Initially 6 entries grown to 8 entries overwriting slot 4 */ + priv->cal_blob =3D NULL; + cs_amp_lib_test_init_dummy_cal_blob(test, 6); + KUNIT_ASSERT_EQ(test, 6, priv->cal_blob->count); + original_blob =3D cs_amp_lib_test_cal_blob_dup(test); + get_random_bytes(&data, sizeof(data)); + data.calTarget[0] =3D 0xaaaaaaaa; /* won't match */ + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, 4, 8, &data= )); + KUNIT_EXPECT_EQ(test, 8, priv->cal_blob->count); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, 8), priv->cal_blo= b->size); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[0], &priv->cal_blob->data[0= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[1], &priv->cal_blob->data[1= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[2], &priv->cal_blob->data[2= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[3], &priv->cal_blob->data[3= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[4], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[5], &priv->cal_blob->data[5= ], sizeof(data)); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[6], sizeof(data= ))); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[7], sizeof(data= ))); +} + +static void cs_amp_lib_test_grow_cal_efi_replace_by_uid(struct kunit *test) +{ + struct cs_amp_lib_test_priv *priv =3D test->priv; + struct device *dev =3D &priv->amp_dev->dev; + const struct cirrus_amp_efi_data *original_blob; + struct cirrus_amp_cal_data data; + + kunit_activate_static_stub(test, + cs_amp_test_hooks->get_efi_variable, + cs_amp_lib_test_get_efi_variable); + kunit_activate_static_stub(test, + cs_amp_test_hooks->set_efi_variable, + cs_amp_lib_test_set_efi_variable); + + /* Initially 1 entry grown to 2 entries overwriting slot 0 */ + cs_amp_lib_test_init_dummy_cal_blob(test, 1); + KUNIT_ASSERT_EQ(test, 1, priv->cal_blob->count); + original_blob =3D cs_amp_lib_test_cal_blob_dup(test); + get_random_bytes(&data, sizeof(data)); + memcpy(data.calTarget, priv->cal_blob->data[0].calTarget, sizeof(data.cal= Target)); + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, -1, 2, &dat= a)); + KUNIT_EXPECT_EQ(test, 2, priv->cal_blob->count); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, 2), priv->cal_blo= b->size); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[0], sizeof(data)); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[1], sizeof(data= ))); + + /* Initially 2 entries grown to 4 entries overwriting slot 1 */ + priv->cal_blob =3D NULL; + cs_amp_lib_test_init_dummy_cal_blob(test, 2); + KUNIT_ASSERT_EQ(test, 2, priv->cal_blob->count); + original_blob =3D cs_amp_lib_test_cal_blob_dup(test); + get_random_bytes(&data, sizeof(data)); + memcpy(data.calTarget, priv->cal_blob->data[1].calTarget, sizeof(data.cal= Target)); + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, -1, 4, &dat= a)); + KUNIT_EXPECT_EQ(test, 4, priv->cal_blob->count); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, 4), priv->cal_blo= b->size); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[0], &priv->cal_blob->data[0= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[1], sizeof(data)); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[2], sizeof(data= ))); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[3], sizeof(data= ))); + + /* Initially 4 entries grown to 6 entries overwriting slot 1 */ + priv->cal_blob =3D NULL; + cs_amp_lib_test_init_dummy_cal_blob(test, 4); + KUNIT_ASSERT_EQ(test, 4, priv->cal_blob->count); + original_blob =3D cs_amp_lib_test_cal_blob_dup(test); + get_random_bytes(&data, sizeof(data)); + memcpy(data.calTarget, priv->cal_blob->data[1].calTarget, sizeof(data.cal= Target)); + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, -1, 6, &dat= a)); + KUNIT_EXPECT_EQ(test, 6, priv->cal_blob->count); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, 6), priv->cal_blo= b->size); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[0], &priv->cal_blob->data[0= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[1], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[2], &priv->cal_blob->data[2= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[3], &priv->cal_blob->data[3= ], sizeof(data)); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[4], sizeof(data= ))); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[5], sizeof(data= ))); + + /* Initially 4 entries grown to 6 entries overwriting slot 3 */ + priv->cal_blob =3D NULL; + cs_amp_lib_test_init_dummy_cal_blob(test, 4); + KUNIT_ASSERT_EQ(test, 4, priv->cal_blob->count); + original_blob =3D cs_amp_lib_test_cal_blob_dup(test); + get_random_bytes(&data, sizeof(data)); + memcpy(data.calTarget, priv->cal_blob->data[3].calTarget, sizeof(data.cal= Target)); + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, -1, 6, &dat= a)); + KUNIT_EXPECT_EQ(test, 6, priv->cal_blob->count); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, 6), priv->cal_blo= b->size); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[0], &priv->cal_blob->data[0= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[1], &priv->cal_blob->data[1= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[2], &priv->cal_blob->data[2= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[3], sizeof(data)); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[4], sizeof(data= ))); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[5], sizeof(data= ))); + + /* Initially 6 entries grown to 8 entries overwriting slot 4 */ + priv->cal_blob =3D NULL; + cs_amp_lib_test_init_dummy_cal_blob(test, 6); + KUNIT_ASSERT_EQ(test, 6, priv->cal_blob->count); + original_blob =3D cs_amp_lib_test_cal_blob_dup(test); + get_random_bytes(&data, sizeof(data)); + memcpy(data.calTarget, priv->cal_blob->data[4].calTarget, sizeof(data.cal= Target)); + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, -1, 8, &dat= a)); + KUNIT_EXPECT_EQ(test, 8, priv->cal_blob->count); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, 8), priv->cal_blo= b->size); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[0], &priv->cal_blob->data[0= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[1], &priv->cal_blob->data[1= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[2], &priv->cal_blob->data[2= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[3], &priv->cal_blob->data[3= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[4], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[5], &priv->cal_blob->data[5= ], sizeof(data)); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[6], sizeof(data= ))); + KUNIT_EXPECT_TRUE(test, mem_is_zero(&priv->cal_blob->data[7], sizeof(data= ))); +} + +static void cs_amp_lib_test_cal_efi_replace_by_uid(struct kunit *test) +{ + struct cs_amp_lib_test_priv *priv =3D test->priv; + struct device *dev =3D &priv->amp_dev->dev; + const struct cirrus_amp_efi_data *original_blob; + struct cirrus_amp_cal_data data; + + kunit_activate_static_stub(test, + cs_amp_test_hooks->get_efi_variable, + cs_amp_lib_test_get_efi_variable); + kunit_activate_static_stub(test, + cs_amp_test_hooks->set_efi_variable, + cs_amp_lib_test_set_efi_variable); + + cs_amp_lib_test_init_dummy_cal_blob(test, 6); + KUNIT_ASSERT_EQ(test, 6, priv->cal_blob->count); + + /* Replace entry matching slot 0 */ + original_blob =3D cs_amp_lib_test_cal_blob_dup(test); + get_random_bytes(&data, sizeof(data)); + memcpy(data.calTarget, priv->cal_blob->data[0].calTarget, sizeof(data.cal= Target)); + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, -1, -1, &da= ta)); + KUNIT_EXPECT_EQ(test, 6, priv->cal_blob->count); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, 6), priv->cal_blo= b->size); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[0], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[1], &priv->cal_blob->data[1= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[2], &priv->cal_blob->data[2= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[3], &priv->cal_blob->data[3= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[4], &priv->cal_blob->data[4= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[5], &priv->cal_blob->data[5= ], sizeof(data)); + + /* Replace entry matching slot 4 */ + original_blob =3D cs_amp_lib_test_cal_blob_dup(test); + get_random_bytes(&data, sizeof(data)); + memcpy(data.calTarget, priv->cal_blob->data[4].calTarget, sizeof(data.cal= Target)); + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, -1, -1, &da= ta)); + KUNIT_EXPECT_EQ(test, 6, priv->cal_blob->count); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, 6), priv->cal_blo= b->size); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[0], &priv->cal_blob->data[0= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[1], &priv->cal_blob->data[1= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[2], &priv->cal_blob->data[2= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[3], &priv->cal_blob->data[3= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[4], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[5], &priv->cal_blob->data[5= ], sizeof(data)); + + /* Replace entry matching slot 3 */ + original_blob =3D cs_amp_lib_test_cal_blob_dup(test); + get_random_bytes(&data, sizeof(data)); + memcpy(data.calTarget, priv->cal_blob->data[3].calTarget, sizeof(data.cal= Target)); + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, -1, -1, &da= ta)); + KUNIT_EXPECT_EQ(test, 6, priv->cal_blob->count); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, 6), priv->cal_blo= b->size); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[0], &priv->cal_blob->data[0= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[1], &priv->cal_blob->data[1= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[2], &priv->cal_blob->data[2= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[3], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[4], &priv->cal_blob->data[4= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[5], &priv->cal_blob->data[5= ], sizeof(data)); + + /* Replace entry matching slot 5 */ + original_blob =3D cs_amp_lib_test_cal_blob_dup(test); + get_random_bytes(&data, sizeof(data)); + memcpy(data.calTarget, priv->cal_blob->data[5].calTarget, sizeof(data.cal= Target)); + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, -1, -1, &da= ta)); + KUNIT_EXPECT_EQ(test, 6, priv->cal_blob->count); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, 6), priv->cal_blo= b->size); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[0], &priv->cal_blob->data[0= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[1], &priv->cal_blob->data[1= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[2], &priv->cal_blob->data[2= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[3], &priv->cal_blob->data[3= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[4], &priv->cal_blob->data[4= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[5], sizeof(data)); +} + +static void cs_amp_lib_test_cal_efi_replace_by_index(struct kunit *test) +{ + struct cs_amp_lib_test_priv *priv =3D test->priv; + struct device *dev =3D &priv->amp_dev->dev; + const struct cirrus_amp_efi_data *original_blob; + struct cirrus_amp_cal_data data; + + kunit_activate_static_stub(test, + cs_amp_test_hooks->get_efi_variable, + cs_amp_lib_test_get_efi_variable); + kunit_activate_static_stub(test, + cs_amp_test_hooks->set_efi_variable, + cs_amp_lib_test_set_efi_variable); + + cs_amp_lib_test_init_dummy_cal_blob(test, 6); + KUNIT_ASSERT_EQ(test, 6, priv->cal_blob->count); + + /* + * Replace entry matching slot 0. + * data.calTarget is deliberately set different to current calTarget + * of the slot to check that the index forces that slot to be used. + */ + original_blob =3D cs_amp_lib_test_cal_blob_dup(test); + get_random_bytes(&data, sizeof(data)); + data.calTarget[0] =3D ~priv->cal_blob->data[0].calTarget[0]; + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, 0, -1, &dat= a)); + KUNIT_EXPECT_EQ(test, 6, priv->cal_blob->count); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, 6), priv->cal_blo= b->size); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[0], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[1], &priv->cal_blob->data[1= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[2], &priv->cal_blob->data[2= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[3], &priv->cal_blob->data[3= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[4], &priv->cal_blob->data[4= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[5], &priv->cal_blob->data[5= ], sizeof(data)); + + /* Replace entry matching slot 4 */ + original_blob =3D cs_amp_lib_test_cal_blob_dup(test); + get_random_bytes(&data, sizeof(data)); + data.calTarget[0] =3D ~priv->cal_blob->data[4].calTarget[0]; + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, 4, -1, &dat= a)); + KUNIT_EXPECT_EQ(test, 6, priv->cal_blob->count); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, 6), priv->cal_blo= b->size); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[0], &priv->cal_blob->data[0= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[1], &priv->cal_blob->data[1= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[2], &priv->cal_blob->data[2= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[3], &priv->cal_blob->data[3= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[4], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[5], &priv->cal_blob->data[5= ], sizeof(data)); + + /* Replace entry matching slot 3 */ + original_blob =3D cs_amp_lib_test_cal_blob_dup(test); + get_random_bytes(&data, sizeof(data)); + data.calTarget[0] =3D ~priv->cal_blob->data[3].calTarget[0]; + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, 3, -1, &dat= a)); + KUNIT_EXPECT_EQ(test, 6, priv->cal_blob->count); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, 6), priv->cal_blo= b->size); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[0], &priv->cal_blob->data[0= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[1], &priv->cal_blob->data[1= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[2], &priv->cal_blob->data[2= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[3], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[4], &priv->cal_blob->data[4= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[5], &priv->cal_blob->data[5= ], sizeof(data)); + + /* Replace entry matching slot 5 */ + original_blob =3D cs_amp_lib_test_cal_blob_dup(test); + get_random_bytes(&data, sizeof(data)); + data.calTarget[0] =3D ~priv->cal_blob->data[5].calTarget[0]; + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, 5, -1, &dat= a)); + KUNIT_EXPECT_EQ(test, 6, priv->cal_blob->count); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, 6), priv->cal_blo= b->size); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[0], &priv->cal_blob->data[0= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[1], &priv->cal_blob->data[1= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[2], &priv->cal_blob->data[2= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[3], &priv->cal_blob->data[3= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[4], &priv->cal_blob->data[4= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[5], sizeof(data)); +} + +static void cs_amp_lib_test_cal_efi_deduplicate(struct kunit *test) +{ + struct cs_amp_lib_test_priv *priv =3D test->priv; + struct device *dev =3D &priv->amp_dev->dev; + const struct cirrus_amp_efi_data *original_blob; + struct cirrus_amp_cal_data data; + int i; + + kunit_activate_static_stub(test, + cs_amp_test_hooks->get_efi_variable, + cs_amp_lib_test_get_efi_variable); + kunit_activate_static_stub(test, + cs_amp_test_hooks->set_efi_variable, + cs_amp_lib_test_set_efi_variable); + + /* + * Replace entry matching slot 0. + * An active entry in slot 1 for the same UID should be marked empty. + * Other entries are unaltered. + */ + cs_amp_lib_test_init_dummy_cal_blob(test, 4); + KUNIT_ASSERT_EQ(test, 4, priv->cal_blob->count); + original_blob =3D cs_amp_lib_test_cal_blob_dup(test); + get_random_bytes(&data, sizeof(data)); + memcpy(data.calTarget, priv->cal_blob->data[1].calTarget, sizeof(data.cal= Target)); + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, 0, -1, &dat= a)); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[0], sizeof(data)); + KUNIT_EXPECT_EQ(test, 0, priv->cal_blob->data[1].calTime[0]); + KUNIT_EXPECT_EQ(test, 0, priv->cal_blob->data[1].calTime[1]); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[2], &priv->cal_blob->data[2= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[3], &priv->cal_blob->data[3= ], sizeof(data)); + + /* + * Replace entry matching slot 1. + * An active entry in slot 0 for the same UID should be marked empty. + * Other entries are unaltered. + */ + priv->cal_blob =3D NULL; + cs_amp_lib_test_init_dummy_cal_blob(test, 4); + KUNIT_ASSERT_EQ(test, 4, priv->cal_blob->count); + original_blob =3D cs_amp_lib_test_cal_blob_dup(test); + get_random_bytes(&data, sizeof(data)); + memcpy(data.calTarget, priv->cal_blob->data[0].calTarget, sizeof(data.cal= Target)); + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, 1, -1, &dat= a)); + KUNIT_EXPECT_EQ(test, 0, priv->cal_blob->data[0].calTime[0]); + KUNIT_EXPECT_EQ(test, 0, priv->cal_blob->data[0].calTime[1]); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[1], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[2], &priv->cal_blob->data[2= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[3], &priv->cal_blob->data[3= ], sizeof(data)); + + /* + * Replace entry matching slot 1. + * An active entry in slot 3 for the same UID should be marked empty. + * Other entries are unaltered. + */ + priv->cal_blob =3D NULL; + cs_amp_lib_test_init_dummy_cal_blob(test, 4); + KUNIT_ASSERT_EQ(test, 4, priv->cal_blob->count); + original_blob =3D cs_amp_lib_test_cal_blob_dup(test); + get_random_bytes(&data, sizeof(data)); + memcpy(data.calTarget, priv->cal_blob->data[3].calTarget, sizeof(data.cal= Target)); + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, 1, -1, &dat= a)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[0], &priv->cal_blob->data[0= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[1], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[2], &priv->cal_blob->data[2= ], sizeof(data)); + KUNIT_EXPECT_EQ(test, 0, priv->cal_blob->data[3].calTime[0]); + KUNIT_EXPECT_EQ(test, 0, priv->cal_blob->data[3].calTime[1]); + + /* + * Worst case, all entries have the same UID + */ + priv->cal_blob =3D NULL; + cs_amp_lib_test_init_dummy_cal_blob(test, 4); + KUNIT_ASSERT_EQ(test, 4, priv->cal_blob->count); + original_blob =3D cs_amp_lib_test_cal_blob_dup(test); + get_random_bytes(&data, sizeof(data)); + for (i =3D 0; i < priv->cal_blob->count; i++) { + priv->cal_blob->data[i].calTarget[0] =3D 0xe5e5e5e5; + priv->cal_blob->data[i].calTarget[1] =3D 0xa7a7a7a7; + } + memcpy(data.calTarget, priv->cal_blob->data[2].calTarget, sizeof(data.cal= Target)); + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, 2, -1, &dat= a)); + KUNIT_EXPECT_EQ(test, 0, priv->cal_blob->data[0].calTime[0]); + KUNIT_EXPECT_EQ(test, 0, priv->cal_blob->data[0].calTime[1]); + KUNIT_EXPECT_EQ(test, 0, priv->cal_blob->data[1].calTime[0]); + KUNIT_EXPECT_EQ(test, 0, priv->cal_blob->data[1].calTime[1]); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[2], sizeof(data)); + KUNIT_EXPECT_EQ(test, 0, priv->cal_blob->data[3].calTime[0]); + KUNIT_EXPECT_EQ(test, 0, priv->cal_blob->data[3].calTime[1]); +} + +static void cs_amp_lib_test_cal_efi_find_free(struct kunit *test) +{ + struct cs_amp_lib_test_priv *priv =3D test->priv; + struct device *dev =3D &priv->amp_dev->dev; + const struct cirrus_amp_efi_data *original_blob; + struct cirrus_amp_cal_data data; + + kunit_activate_static_stub(test, + cs_amp_test_hooks->get_efi_variable, + cs_amp_lib_test_get_efi_variable); + kunit_activate_static_stub(test, + cs_amp_test_hooks->set_efi_variable, + cs_amp_lib_test_set_efi_variable); + + cs_amp_lib_test_init_dummy_cal_blob(test, 6); + KUNIT_ASSERT_EQ(test, 6, priv->cal_blob->count); + + /* + * Slot 0 is empty. + * data.calTarget is set to a value that won't match any existing entry. + */ + memset(&priv->cal_blob->data[0].calTime, 0, sizeof(priv->cal_blob->data[0= ].calTime)); + original_blob =3D cs_amp_lib_test_cal_blob_dup(test); + get_random_bytes(&data, sizeof(data)); + data.calTarget[0] =3D 0xaaaaaaaa; + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, -1, -1, &da= ta)); + KUNIT_EXPECT_EQ(test, 6, priv->cal_blob->count); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, 6), priv->cal_blo= b->size); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[0], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[1], &priv->cal_blob->data[1= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[2], &priv->cal_blob->data[2= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[3], &priv->cal_blob->data[3= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[4], &priv->cal_blob->data[4= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[5], &priv->cal_blob->data[5= ], sizeof(data)); + + /* Slot 4 is empty */ + memset(&priv->cal_blob->data[4].calTime, 0, sizeof(priv->cal_blob->data[4= ].calTime)); + original_blob =3D cs_amp_lib_test_cal_blob_dup(test); + get_random_bytes(&data, sizeof(data)); + data.calTarget[0] =3D 0xaaaaaaaa; + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, -1, -1, &da= ta)); + KUNIT_EXPECT_EQ(test, 6, priv->cal_blob->count); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, 6), priv->cal_blo= b->size); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[0], &priv->cal_blob->data[0= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[1], &priv->cal_blob->data[1= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[2], &priv->cal_blob->data[2= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[3], &priv->cal_blob->data[3= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[4], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[5], &priv->cal_blob->data[5= ], sizeof(data)); + + /* Slot 3 is empty */ + memset(&priv->cal_blob->data[3].calTime, 0, sizeof(priv->cal_blob->data[3= ].calTime)); + original_blob =3D cs_amp_lib_test_cal_blob_dup(test); + get_random_bytes(&data, sizeof(data)); + data.calTarget[0] =3D 0xaaaaaaaa; + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, -1, -1, &da= ta)); + KUNIT_EXPECT_EQ(test, 6, priv->cal_blob->count); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, 6), priv->cal_blo= b->size); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[0], &priv->cal_blob->data[0= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[1], &priv->cal_blob->data[1= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[2], &priv->cal_blob->data[2= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[3], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[4], &priv->cal_blob->data[4= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[5], &priv->cal_blob->data[5= ], sizeof(data)); + + /* Replace entry matching slot 5 */ + memset(&priv->cal_blob->data[5].calTime, 0, sizeof(priv->cal_blob->data[5= ].calTime)); + original_blob =3D cs_amp_lib_test_cal_blob_dup(test); + get_random_bytes(&data, sizeof(data)); + data.calTarget[0] =3D 0xaaaaaaaa; + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, -1, -1, &da= ta)); + KUNIT_EXPECT_EQ(test, 6, priv->cal_blob->count); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, 6), priv->cal_blo= b->size); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[0], &priv->cal_blob->data[0= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[1], &priv->cal_blob->data[1= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[2], &priv->cal_blob->data[2= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[3], &priv->cal_blob->data[3= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[4], &priv->cal_blob->data[4= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[5], sizeof(data)); +} + +static void cs_amp_lib_test_cal_efi_bad_cal_target(struct kunit *test) +{ + struct cs_amp_lib_test_priv *priv =3D test->priv; + struct device *dev =3D &priv->amp_dev->dev; + struct cirrus_amp_cal_data data; + + kunit_activate_static_stub(test, + cs_amp_test_hooks->get_efi_variable, + cs_amp_lib_test_get_efi_variable); + kunit_activate_static_stub(test, + cs_amp_test_hooks->set_efi_variable, + cs_amp_lib_test_set_efi_variable); + + cs_amp_lib_test_init_dummy_cal_blob(test, 4); + + /* Zero calTarget is illegal */ + get_random_bytes(&data, sizeof(data)); + memset(data.calTarget, 0, sizeof(data.calTarget)); + KUNIT_EXPECT_LT(test, cs_amp_set_efi_calibration_data(dev, -1, -1, &data)= , 0); + KUNIT_EXPECT_LT(test, cs_amp_set_efi_calibration_data(dev, 0, -1, &data),= 0); + KUNIT_EXPECT_LT(test, cs_amp_set_efi_calibration_data(dev, 0, 2, &data), = 0); +} + +static void cs_amp_lib_test_cal_efi_write_denied(struct kunit *test) +{ + struct cs_amp_lib_test_priv *priv =3D test->priv; + struct device *dev =3D &priv->amp_dev->dev; + const struct cirrus_amp_efi_data *original_blob; + struct cirrus_amp_cal_data data; + + kunit_activate_static_stub(test, + cs_amp_test_hooks->get_efi_variable, + cs_amp_lib_test_get_efi_variable); + kunit_activate_static_stub(test, + cs_amp_test_hooks->set_efi_variable, + cs_amp_lib_test_set_efi_variable_denied); + + cs_amp_lib_test_init_dummy_cal_blob(test, 4); + KUNIT_ASSERT_EQ(test, 4, priv->cal_blob->count); + original_blob =3D cs_amp_lib_test_cal_blob_dup(test); + get_random_bytes(&data, sizeof(data)); + + /* Unspecified slot */ + KUNIT_EXPECT_LT(test, cs_amp_set_efi_calibration_data(dev, -1, -1, &data)= , 0); + KUNIT_EXPECT_MEMEQ(test, original_blob, priv->cal_blob, original_blob->si= ze); + + /* Unspecified slot with size */ + KUNIT_EXPECT_LT(test, cs_amp_set_efi_calibration_data(dev, -1, 6, &data),= 0); + KUNIT_EXPECT_MEMEQ(test, original_blob, priv->cal_blob, original_blob->si= ze); + + /* Specified slot */ + KUNIT_EXPECT_LT(test, cs_amp_set_efi_calibration_data(dev, 1, -1, &data),= 0); + KUNIT_EXPECT_MEMEQ(test, original_blob, priv->cal_blob, original_blob->si= ze); + + /* Specified slot with size */ + KUNIT_EXPECT_LT(test, cs_amp_set_efi_calibration_data(dev, 1, 6, &data), = 0); + KUNIT_EXPECT_MEMEQ(test, original_blob, priv->cal_blob, original_blob->si= ze); +} + +static void cs_amp_lib_test_cal_efi_attr_preserved(struct kunit *test) +{ + struct cs_amp_lib_test_priv *priv =3D test->priv; + struct device *dev =3D &priv->amp_dev->dev; + struct cirrus_amp_cal_data data; + + kunit_activate_static_stub(test, + cs_amp_test_hooks->get_efi_variable, + cs_amp_lib_test_get_efi_variable); + kunit_activate_static_stub(test, + cs_amp_test_hooks->set_efi_variable, + cs_amp_lib_test_set_efi_variable); + + cs_amp_lib_test_init_dummy_cal_blob(test, 6); + KUNIT_ASSERT_EQ(test, 6, priv->cal_blob->count); + memset(&priv->cal_blob->data[0], 0, sizeof(priv->cal_blob->data[0])); + get_random_bytes(&data, sizeof(data)); + + /* Set a non-standard attr to return from get_efi_variable() */ + priv->efi_attr =3D EFI_VARIABLE_HARDWARE_ERROR_RECORD; + + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, -1, -1, &da= ta)); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[0], sizeof(data)); + KUNIT_EXPECT_EQ(test, priv->efi_attr, EFI_VARIABLE_HARDWARE_ERROR_RECORD); +} + +static efi_status_t cs_amp_lib_test_set_hp_efi_cal_variable(efi_char16_t *= name, + efi_guid_t *guid, + u32 attr, + unsigned long size, + void *buf) +{ + static const efi_char16_t expected_name[] =3D HP_CALIBRATION_EFI_NAME; + static const efi_guid_t expected_guid =3D HP_CALIBRATION_EFI_GUID; + struct kunit *test =3D kunit_get_current_test(); + struct cs_amp_lib_test_priv *priv =3D test->priv; + + KUNIT_ASSERT_NOT_NULL(test, name); + KUNIT_ASSERT_NOT_NULL(test, guid); + + if (memcmp(name, expected_name, sizeof(expected_name)) || + efi_guidcmp(*guid, expected_guid)) + return -EFI_ACCESS_DENIED; + + KUNIT_ASSERT_NOT_NULL(test, buf); + KUNIT_ASSERT_NE(test, 0, size); + + kunit_kfree(test, priv->cal_blob); + priv->cal_blob =3D kunit_kmalloc(test, size, GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, priv->cal_blob); + memcpy(priv->cal_blob, buf, size); + priv->efi_attr =3D attr; + + return EFI_SUCCESS; +} + +/* + * If the HP EFI exists it should be the one that is updated. + */ +static void cs_amp_lib_test_cal_efi_update_hp(struct kunit *test) +{ + struct cs_amp_lib_test_priv *priv =3D test->priv; + struct device *dev =3D &priv->amp_dev->dev; + const struct cirrus_amp_efi_data *original_blob; + struct cirrus_amp_cal_data data; + + kunit_activate_static_stub(test, + cs_amp_test_hooks->get_efi_variable, + cs_amp_lib_test_get_hp_cal_efi_variable); + kunit_activate_static_stub(test, + cs_amp_test_hooks->set_efi_variable, + cs_amp_lib_test_set_hp_efi_cal_variable); + + cs_amp_lib_test_init_dummy_cal_blob(test, 6); + KUNIT_ASSERT_EQ(test, 6, priv->cal_blob->count); + + /* Replace entry matching slot 4 */ + original_blob =3D cs_amp_lib_test_cal_blob_dup(test); + get_random_bytes(&data, sizeof(data)); + data.calTarget[0] =3D ~priv->cal_blob->data[4].calTarget[0]; + KUNIT_EXPECT_EQ(test, 0, cs_amp_set_efi_calibration_data(dev, 4, -1, &dat= a)); + KUNIT_EXPECT_EQ(test, 6, priv->cal_blob->count); + KUNIT_EXPECT_EQ(test, struct_size(priv->cal_blob, data, 6), priv->cal_blo= b->size); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[0], &priv->cal_blob->data[0= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[1], &priv->cal_blob->data[1= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[2], &priv->cal_blob->data[2= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[3], &priv->cal_blob->data[3= ], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &data, &priv->cal_blob->data[4], sizeof(data)); + KUNIT_EXPECT_MEMEQ(test, &original_blob->data[5], &priv->cal_blob->data[5= ], sizeof(data)); +} + static void cs_amp_lib_test_spkid_lenovo_not_present(struct kunit *test) { struct cs_amp_lib_test_priv *priv =3D test->priv; @@ -1072,6 +2433,28 @@ static struct kunit_case cs_amp_lib_test_cases[] =3D= { KUNIT_CASE(cs_amp_lib_test_read_cal_data_test), KUNIT_CASE(cs_amp_lib_test_write_ambient_test), =20 + /* Test cases for writing cal data to UEFI */ + KUNIT_CASE(cs_amp_lib_test_create_new_cal_efi), + KUNIT_CASE(cs_amp_lib_test_create_new_cal_efi_indexed), + KUNIT_CASE(cs_amp_lib_test_create_new_cal_efi_indexed_no_max), + KUNIT_CASE(cs_amp_lib_test_cal_efi_all_zeros_add_first), + KUNIT_CASE(cs_amp_lib_test_cal_efi_all_zeros_add_first_no_shrink), + KUNIT_CASE(cs_amp_lib_test_cal_efi_all_zeros_add_first_indexed), + KUNIT_CASE(cs_amp_lib_test_cal_efi_all_zeros_add_first_indexed_no_shrink), + KUNIT_CASE(cs_amp_lib_test_grow_append_cal_efi), + KUNIT_CASE(cs_amp_lib_test_grow_append_cal_efi_indexed), + KUNIT_CASE(cs_amp_lib_test_grow_append_cal_efi_indexed_no_max), + KUNIT_CASE(cs_amp_lib_test_grow_cal_efi_replace_indexed), + KUNIT_CASE(cs_amp_lib_test_grow_cal_efi_replace_by_uid), + KUNIT_CASE(cs_amp_lib_test_cal_efi_replace_by_uid), + KUNIT_CASE(cs_amp_lib_test_cal_efi_replace_by_index), + KUNIT_CASE(cs_amp_lib_test_cal_efi_deduplicate), + KUNIT_CASE(cs_amp_lib_test_cal_efi_find_free), + KUNIT_CASE(cs_amp_lib_test_cal_efi_bad_cal_target), + KUNIT_CASE(cs_amp_lib_test_cal_efi_write_denied), + KUNIT_CASE(cs_amp_lib_test_cal_efi_attr_preserved), + KUNIT_CASE(cs_amp_lib_test_cal_efi_update_hp), + /* Test cases for speaker ID */ KUNIT_CASE(cs_amp_lib_test_spkid_lenovo_not_present), KUNIT_CASE(cs_amp_lib_test_spkid_lenovo_d0), diff --git a/sound/soc/codecs/cs-amp-lib.c b/sound/soc/codecs/cs-amp-lib.c index 7038574e3f4b..d8f8b0259cd1 100644 --- a/sound/soc/codecs/cs-amp-lib.c +++ b/sound/soc/codecs/cs-amp-lib.c @@ -727,6 +727,7 @@ EXPORT_SYMBOL_NS_GPL(cs_amp_create_debugfs, "SND_SOC_CS= _AMP_LIB"); =20 static const struct cs_amp_test_hooks cs_amp_test_hook_ptrs =3D { .get_efi_variable =3D cs_amp_get_efi_variable, + .set_efi_variable =3D cs_amp_set_efi_variable, .write_cal_coeff =3D cs_amp_write_cal_coeff, .read_cal_coeff =3D cs_amp_read_cal_coeff, }; --=20 2.47.3