From nobody Sat Feb 7 17:19:48 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 DF09F324B37; Thu, 16 Oct 2025 10:43:07 +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=1760611391; cv=fail; b=ZYEzuOfdjSNlVmx96R4Cosl4LuZt/IEeTBEVDCl/W+B0BXwOtl/is+i/yaW+OyV9QVejRttVMoXMMbBaDzFq2k76L/B/g4sTRm85QbeDcg5MAw7a8E9P9eqT54xo8rr7qwz4DPX6E3JR8dQ88UuZff4nGREWbzTI6YD8jIBBLbA= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760611391; c=relaxed/simple; bh=FQ7UZlVELcjZgjKQjNasYALWJmgz7+VXSDXphGExO1k=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=jnt2Fn2fQOq1ORMa2UF821Xci10aSN0FUtYuYP8aeE0mrTIp13L+NKYjqDOM5TqLQSIfLTyBb/HNmjSGIS+96IPcPneuLDmhZ7mxYf/byJ5abVrsOaIit56mYMIuYrtBBYubcGzKi63nZXb9wzvHAt1Auo/si4sTDuPgIwyIIxQ= 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=Kpu+pRE+; dkim=pass (1024-bit key) header.d=cirrus4.onmicrosoft.com header.i=@cirrus4.onmicrosoft.com header.b=RaPnyFc1; 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="Kpu+pRE+"; dkim=pass (1024-bit key) header.d=cirrus4.onmicrosoft.com header.i=@cirrus4.onmicrosoft.com header.b="RaPnyFc1" 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 59G9oCCU648147; Thu, 16 Oct 2025 05:42:51 -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=lthRXyn0c+A5/Sw/F3g3Z1vbY8O5qid4NfzABOcSPjQ=; b= Kpu+pRE+B3xo8u1tP3AuO0yPtaociipkHshEDOqyb4iMTiVKfvi7IdDiFO7j8kRQ 5MXeGimIs0dnT9SRC0g18z2m5lr1RmLIghepBaNcH3Af1c/fUfGatQKTZiq+ukFJ QpSUjJwmhTqLS+ipYK4qt4sRmROL3mljUDo26NuANMPKMCwoR019M+DlI6SBgCdV TH5RagdLtmkRNOAQTmW2dr0v7pY8FNqPgLdpf5plnLuvrMtdSqbYHcZyhl2gi6xI Ct1nrD4QoOCrGasC5/C42Qf4P7WZF4MaE+hpI9KNctcGKRGLMUDE9AtmWJhggfGs 1TJzwhz88bxT4X3OXWTJIQ== Received: from ch5pr02cu005.outbound.protection.outlook.com (mail-northcentralusazon11022120.outbound.protection.outlook.com [40.107.200.120]) by mx0b-001ae601.pphosted.com (PPS) with ESMTPS id 49sdb448a2-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Thu, 16 Oct 2025 05:42:50 -0500 (CDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=BQ/sD/GhRepmGaigrPoc+ztgG7OFMb3O2/jvc5lqEvU/XEwxime/HoRM6U0PXbxavJENgVUZsJkPFbT0/2BCcJG1Mwztv1PduCwqvulWJxoCQ63n/GHq5ueHnkvTI+0/Z2RLr9kEqOdaHmzV1sSs2UQ6xUmoEN2vATj2kJa1e2cCmQAqazNTww++WFmWke2dlHjC4p4NXg5/XRdaWOd3/z4JXk36yt6Irmleyu7sGrHAnaeLdC4yVne1zD50LD5yYomRDceoZC5xek7mwdbRKzlu0dtqO7pdrnsQRm80BSKC/TR5Bmn6J0K8ho9xIOyDBM0ts3RBN85u2CakE3sFcA== 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=lthRXyn0c+A5/Sw/F3g3Z1vbY8O5qid4NfzABOcSPjQ=; b=o80ofdK4w5sXHLkM8Ri5jTgVl6AfV3EH9C4n9gHK70QXd5XCsO7uLW3U4+lYl/re7N95QrVyplxc+Y/v0EsEpZjx/r+P3ke1V1+s5oNG8nIlkC5/R1SsvuOPx1bp4fYp3aPkzLD5C9o/6MK9Gn9TVavx8UlCW9v/5oILVW2QIHCCCHDdGbmGvFcBCOPIe7y2n98zwHm4BRxwIAJPcuEaY26y2P1iHOyAo5K2DmztaAp2N9ZtFh0DTnUxTmLpnQyJCq+qZZ5yxEmQ7fxCvG59cAlTdM/Z8NpjdunQIzynrDWUxckOwvIHuMLbOGZBMfhUCEoxekTySxj4VvzCxSrl+g== 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=lthRXyn0c+A5/Sw/F3g3Z1vbY8O5qid4NfzABOcSPjQ=; b=RaPnyFc1BKAUNO4zP1fmJqDhhXKj/TufFMwzn45kamdN8wFZQ6TjF7pf6jlYVrDnGmvPkxUP6w6Bx/t0zgcWwDyD01Dm7wTzFHkVItNK7BjAN9bjHKwSbNa8x9XIUZBO4y2g21lJfPDiZPBFgRT6lE0G9oVYAR9nxXrJG1CbXCM= Received: from MN0PR02CA0022.namprd02.prod.outlook.com (2603:10b6:208:530::25) by DM6PR19MB4247.namprd19.prod.outlook.com (2603:10b6:5:2b8::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9228.13; Thu, 16 Oct 2025 10:42:44 +0000 Received: from MN1PEPF0000F0E5.namprd04.prod.outlook.com (2603:10b6:208:530:cafe::29) by MN0PR02CA0022.outlook.office365.com (2603:10b6:208:530::25) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9228.13 via Frontend Transport; Thu, 16 Oct 2025 10:42:44 +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 MN1PEPF0000F0E5.mail.protection.outlook.com (10.167.242.43) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9228.7 via Frontend Transport; Thu, 16 Oct 2025 10:42:43 +0000 Received: from ediswmail9.ad.cirrus.com (ediswmail9.ad.cirrus.com [198.61.86.93]) by edirelay1.ad.cirrus.com (Postfix) with ESMTPS id C2AA240654B; Thu, 16 Oct 2025 10:42:42 +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 9FB09822540; Thu, 16 Oct 2025 10:42:42 +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 01/11] ASoC: cs35l56: Read silicon ID during initialization and save it Date: Thu, 16 Oct 2025 11:42:32 +0100 Message-ID: <20251016104242.157325-2-rf@opensource.cirrus.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251016104242.157325-1-rf@opensource.cirrus.com> References: <20251016104242.157325-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: MN1PEPF0000F0E5:EE_|DM6PR19MB4247:EE_ X-MS-Office365-Filtering-Correlation-Id: 7d5cc973-1243-4de5-c1c2-08de0ca0bcfb X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|61400799027|376014|36860700013|82310400026; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?iRR4S8O1bV+N8my+N9q+4uvOHvH+msNUOnntS6VsGbkt8xqV/s3lYoKS3msx?= =?us-ascii?Q?PSWxckDcmCI3MixhhMgKjndpPGbBWn/jc06FBCILbdzSJljxbIg/QD2EWbuv?= =?us-ascii?Q?W6EHnEwcNLmMN+XAMp1q3mVCJSzZl1+BoBrFdZBVuTn7PtSlTlDc+zlg614D?= =?us-ascii?Q?j85tv5ESTNMsrcNJg0zuPx0KzQPtQAd5q+PkSc1cGU86qYc1WxqGuCzwW18+?= =?us-ascii?Q?kv8QU5h7sLO9wKYoG9nPTvKYPOJMItHEolQmElmStE6TygNaWVF6MCfS3UVG?= =?us-ascii?Q?327ngH5ZHqz3Ft3t0sjmYPDV2Gd6VlpBAfuFqDYJb4s/0Ntub551dHMHCp58?= =?us-ascii?Q?Ba7sq7B8wGbnEVLDwcMEntC23iq5LF8WiqH4XCb9HBcHjUQvmI7NOsWhAw7Y?= =?us-ascii?Q?fBx8JioeXsBNhYgb08bEqWzOxouaOjDcczpUpO9h78V3wqX8gMSL4t63rYuL?= =?us-ascii?Q?J+KIxdXbIcSl5Yb9kGHwWDJBqu4K6tWodVTgVkiPEWi0PkfcWV6uNDX/KjOl?= =?us-ascii?Q?zyEjh9iP2vloMlnDjssDfSCRWA07jqUP6KnxFxATLiR7ab9bL8fn6n+vBGYp?= =?us-ascii?Q?+fIONfkJJMu13CCafvqETIdC4xiqdWaIGSvxGr6/AwJqPjB/+k+obI0XNjJS?= =?us-ascii?Q?S5qKmT3HtpmUtk5Z0pe8ZN86mnuLoZ/hKFwigp3UuBOeQyzMHlCHM9hV9mz1?= =?us-ascii?Q?0Qge0dQ80ZXDkop7TQF2gTHmuTskR7ipZlTuLZ9XTVY0NfUAdrvTHCOedI2S?= =?us-ascii?Q?Lbw3VXXGm6MIJVsU3tTliuxeFZNNM7H6mDUK+mLKFon4hyXCLUSNtw1XLnRE?= =?us-ascii?Q?m1D5MIXVHBnJPHoffwo7s65O67PQFB4ThOM+1LdzGBBC8YvrRgotfG97Brya?= =?us-ascii?Q?C5sX9p2I/C4RDsqlvFQkT50W5VWP99eDOoGQFPkiZN4glvDj2bst8SOun9By?= =?us-ascii?Q?BOxNywk0gaDS1OwFJ9l+6w3KrBxF2QRWMEghH1t+WghH1p4+NcJxq7Bmv+tM?= =?us-ascii?Q?lo9fvPaBDmaHQqjGB6On2y78VsLORVI/g1xlKK+oFQZOs3GnIfmcSVzL8EcD?= =?us-ascii?Q?jbHaA56YAgnykJO0DyPP1QeeaM9V8JWmVho/EUj3FUTBpXiWvqV+sGl14hRi?= =?us-ascii?Q?egq6//blm0TPJhgBadCOh/AnnD1saghqb91w/uLlchnF5UPuzE1yjQ/hCL0p?= =?us-ascii?Q?53DWrRhDxyjpEbP8d/Wx5WZ7pNf3uReJG+dDYksKp5tFsslPV4qZ3EGPlRm/?= =?us-ascii?Q?/d8gxoKlrDpzflmEf52PXJLzLKpts1PDpdORJASxi7A3hzyPdvK2xbQX3JEc?= =?us-ascii?Q?JqieoSoRyqdiFK5YWt4dXno6hKHp6mZxyu5M7z++Cpwv/Ulbuc/w8sM45lvr?= =?us-ascii?Q?d1BNzRH7szSWqZkjg6q0yID+aoPOVFk06R0tgzPKCLgLlbcAiACMI9ojoRM6?= =?us-ascii?Q?QLdJp7edEqQ9mmBcaJHj447CxQKnwM35LCYommyucNSu0F8tg4UeJ/gsHuRq?= =?us-ascii?Q?QDEOycg/EnHwmAutlnNrbYbLL0038QxI0iVUY3Kp1apMJ6ehYB+PZ5CTtFTD?= =?us-ascii?Q?Y3LuzgzyFe6ZpabXb6w=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)(376014)(36860700013)(82310400026);DIR:OUT;SFP:1102; X-OriginatorOrg: opensource.cirrus.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 16 Oct 2025 10:42:43.6028 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 7d5cc973-1243-4de5-c1c2-08de0ca0bcfb 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-MN1PEPF0000F0E5.namprd04.prod.outlook.com X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR19MB4247 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMDE2MDA4MCBTYWx0ZWRfX4UvyZAGHCATy zuMWKd/YwCfIHfRHAH07l7qY3pP008xef03iNajWtKnDDP2izDW3/G6YD/T4kXzUoetNuMjqZL6 vWIUyLlLzkNxVEhN4fiZ4wnUP9Hg53qiBc7LrMesagkkc36iRLpKpfFLLt6CQMeGuUxTLnmYwbc VLlnqhtXeQBuAvyP8hBmD17BBI1sP1sltdsBGYqOMONY1Bive6ZpvJd64GlQwECm1MkHGIMAwed ivHPptGHR5oM5N57bjxlOaoZAcBWULPAYtdbtKtvj4cKalOmwukYD+3FellABxbnAQSOV0sij/t sjnFMuGrdV0d0wOKR5HUBbR6T1dnaFT3VhGyzs432iKU1II/W37LjDVJzOnw27ySxHsP8Perf8v 1nFojBfuE7Dk2hfAsSJcNNnAYfqgBA== X-Proofpoint-GUID: oueNDLSMmUm0xDn4Bup1w-zF-dLKVmEz X-Authority-Analysis: v=2.4 cv=PPICOPqC c=1 sm=1 tr=0 ts=68f0cc2a cx=c_pps a=3SCk7X9PwWHtu4c5+rqWlQ==: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-ORIG-GUID: oueNDLSMmUm0xDn4Bup1w-zF-dLKVmEz 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 --- 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 Sat Feb 7 17:19:48 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 724E9328613; Thu, 16 Oct 2025 10:42:55 +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=1760611377; cv=fail; b=V2/lKDkFXiZ59NbFKs7+ZPrNLUCNI2+gcPjVLs5zqNOoEjofYXZ92yQu/kp59+WXSQSh1BvcQ9LxHPPzlhU5omOD2n7/H3Cyjgd1l//fGaq2D/5YaLa2b3c8Gemg7W2g3DDDpSsTzlmHfjZMYyrrsSNpdhtqU/75eOnwmMKPNt0= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760611377; c=relaxed/simple; bh=h+yuoSLb/4Npj6Ip0+ySsiDdjRsYailZPVotrd8JeKs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=hTuL4o7AHMcV8k2XuRJXO28x5D78WPzj6LJZmhb0850R3xWmRfCSkoOcrVbYLf53t+vuFEk43PBsmS42UrsP3Mgkybqcscj4PoufipXvwtcsPDOJND7/QKjmFLuAsEoR9tnDqNK9r3hW4Urg5Z1zq759tJ3Hui1Vl/qXJlJzk0k= 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=g6cU36o1; dkim=pass (1024-bit key) header.d=cirrus4.onmicrosoft.com header.i=@cirrus4.onmicrosoft.com header.b=xKW7YxAp; 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="g6cU36o1"; dkim=pass (1024-bit key) header.d=cirrus4.onmicrosoft.com header.i=@cirrus4.onmicrosoft.com header.b="xKW7YxAp" 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 59FMZLZr298642; Thu, 16 Oct 2025 05:42:52 -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=Xnbntad9ZR0FIrRG75/FBjqDE1iTZuCeewzJLjhw4qw=; b= g6cU36o1U6Kp/BYarXyoPWwG+ubIc9LOIzopa22W2sxLjYQ+Uw2PG9V5Bh3xZmF4 c70Muryl7YW4zfjFxXlPysrEWM68eT6AHYSdWY5chIb5q+99+CXlMLl9Bav4nXPs /nZTORC9uwm8GuwfyRc1wrMydwUfLRTPTewuNwvuiyE5jrqe90nI0cgY1PclT13M jPWy5pfez0XoDhqi8CdNUhnGHD4OQKw2V9oeAsmDdPHhBQ4gGXTq8Y2o6NpWy9jb 4ImUgtsmeZeBC92yJyHlughbKcqYP7y1fUXW0N+B0HmxnB8dxlbJvK05sX8DB0cC xMl9/nuLrunhErG8WKg2cg== Received: from dm5pr21cu001.outbound.protection.outlook.com (mail-centralusazon11021141.outbound.protection.outlook.com [52.101.62.141]) by mx0a-001ae601.pphosted.com (PPS) with ESMTPS id 49t9mhhpx2-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Thu, 16 Oct 2025 05:42:51 -0500 (CDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=IG0wRw5Nx0eoUbDV1PvEOtkghiPw2Qtal3TdNJAif8kIv3jD2N1dE9ihCYGh3A/EqMBc8/653eQRgC3OFvGVJUOIv2D1IWRPnJGV57hKYFcRIQ1DfiwzUOoscPP2iqy7osZQkuxyd+qbOCaxYEgl/yEhi0x2jNYqLceiZfSlu8CFEw+YCK46Ge3T4JIgC/InU+JjaRmipvFcnDokAxrFyL4hgBukR8FuSZsd3PVbhDNgiKJR0cqVK6H+5/iJJ09KEa53FKBs1vGWGeWjrJp1dp1Bh0ZJ6hnkVMa0624vzfi6YRAyQpPY0CzG/aHWJgDVClLH/iKPLJ9E2QtqUWGHpw== 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=Xnbntad9ZR0FIrRG75/FBjqDE1iTZuCeewzJLjhw4qw=; b=ve0l3dOWa8oHXvQzaZWXdBqpDJshG+l8j+947s2d4k606e37dPoKXQkoWz3L/Ik/74bPTZ9U+e9i2KdK//7tR+EYm5y15Q3T0we0I6AsYbbKah9+CSCdSzAEnO5CRKY2pskisXcwt/v87M5IZ24sD8cXcF6lhozF1J99EEnHqj1EhLrEZd3KLb32HdG0AGBp+7MmAPOYDPJ0TMpxqABdLeAtwanQoNJNDZOO/Ku6d1Ef/zam2VsZdTvySb8rW38XjrENsumfFULb5ayXAZ29AQrRV9GnxbTo3XqLTi0U5xRz/hvSQjf/qkBAW9Ndsjl5eZVK/i7W1rnrVxPeMoEDCQ== 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=Xnbntad9ZR0FIrRG75/FBjqDE1iTZuCeewzJLjhw4qw=; b=xKW7YxApJnW6xLiYT5sussYDgj6JLCPVRyyKKa6+pPuerR3mJlB8CxWm/SeOj/uYX5ZW7vWRvfbLhnkc92SfE8KJdTCmDy66pXOlf4VYKvQ71s2i/sif3/2gQ3Fzb4WtzC2RsjZr9Wy6o8jQ1mlf4XvRtkGnWyuT37+BC8NoZ40= Received: from MW4PR03CA0340.namprd03.prod.outlook.com (2603:10b6:303:dc::15) by SA3PR19MB7301.namprd19.prod.outlook.com (2603:10b6:806:316::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9228.12; Thu, 16 Oct 2025 10:42:45 +0000 Received: from SJ1PEPF00001CDF.namprd05.prod.outlook.com (2603:10b6:303:dc:cafe::7a) by MW4PR03CA0340.outlook.office365.com (2603:10b6:303:dc::15) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9228.11 via Frontend Transport; Thu, 16 Oct 2025 10:42:45 +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 SJ1PEPF00001CDF.mail.protection.outlook.com (10.167.242.7) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9228.7 via Frontend Transport; Thu, 16 Oct 2025 10:42:44 +0000 Received: from ediswmail9.ad.cirrus.com (ediswmail9.ad.cirrus.com [198.61.86.93]) by edirelay1.ad.cirrus.com (Postfix) with ESMTPS id CD309406552; Thu, 16 Oct 2025 10:42:42 +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 AD397822541; Thu, 16 Oct 2025 10:42:42 +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 02/11] ASoC: cs-amp-lib: Add helpers for factory calibration Date: Thu, 16 Oct 2025 11:42:33 +0100 Message-ID: <20251016104242.157325-3-rf@opensource.cirrus.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251016104242.157325-1-rf@opensource.cirrus.com> References: <20251016104242.157325-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: SJ1PEPF00001CDF:EE_|SA3PR19MB7301:EE_ X-MS-Office365-Filtering-Correlation-Id: 7e37ebc7-7a49-483c-c69f-08de0ca0bd5b 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?azAXU72VZXx6fNIQe1gp1BSE+FYvaUJOXm3L79YmVMbRGRAAaagGrNhnInoQ?= =?us-ascii?Q?dcX0wt0StJW2z7KXoUUXbwiIYCioFVbx/9FFFzXBzgZ8peFyf80LTWiPFGsd?= =?us-ascii?Q?MMVggzNAGQrKIEOBraD1NYRK5PXFkaAZernS3E9z6zurTwpnvBXRGNSpzboj?= =?us-ascii?Q?akSR4HRa7+HvoRGM4RR1hmQIZDXpgqqq+VYTZaJcu3ew5KB/mSlP3B/vlyxM?= =?us-ascii?Q?Q5Or42ZlelNDY4zmaf1m6AsiC282yrCBiYgLR1Ful2PRSobDY5EFpnhONVhg?= =?us-ascii?Q?BTwL+FBTuj2pJaK068SxQ7IR/7h//Q1xPZ/tKzbpDGUEUUJP841wJXzkAZaH?= =?us-ascii?Q?y2NlGaaM7Y1F9gMUztQCbZF3dVcsFGQqtQN7Xo/yPJgYX2pce2hqzNKcBIQl?= =?us-ascii?Q?7bz27VWTOpeuR0ivSoCbo/UYCvMT2yZHbafTQqhmrhk1bcglWLpGOzKHyEmL?= =?us-ascii?Q?WTUlFRKD+FJEPAklcEBolEVP62zXKQQ06EVXXstZcnCf8YdOfu3tUu2GvxMe?= =?us-ascii?Q?Q4qUUhNRyYQVyEieaHscK9W7cLFSbk8iVqR5hVMl5J1O6oJNxu1M85iDUvhh?= =?us-ascii?Q?ThsvDYG//Vx5KUKUSx6JXBtb7HCyHp7AuoeOJt3TsALL73iMK1l/Bn8CC288?= =?us-ascii?Q?al4gtV0/dKaWz6b5qdNOzl5yUPxQdwxMggNd8cYZtjoPQLRKaESSBU246/cp?= =?us-ascii?Q?syU+V4Fq7fcGIrdDGwTQHZyDyxAVjg6n10FRPtvd7KmhaLd+8j2LzG3Ne3LS?= =?us-ascii?Q?8HZeVRTmurGhXMfkZW/oIosIB74kz6JLRaJVvgpsRXM1i6yAqqPdY4O4/HwR?= =?us-ascii?Q?aKwIM+u7Yk81jajkktU57j4o1pzuyanNmQrDJqWeALy2+F9+t6Ib8DJEw9NB?= =?us-ascii?Q?bQ9afn8vMDZymM8LUrVIpr4VHTif+FAXuro3KVknDuSoamgl68RZsjRzUQre?= =?us-ascii?Q?d1+3mk8kK2TfJba8LDnHBRwJEHnzjdcNL7kqjB8tq5CXTlavIlABYExrIUh3?= =?us-ascii?Q?0S2ErpHrKtJnWG4GXlEWPfnmHzbYhyp9PIX/diEgcGp0FMyg5yWztzOIgudo?= =?us-ascii?Q?wrCXdXsezj8XD0B/8u7amZ8G/+gPskERbK3zCDpbYyOp6xHhWm/kuVlj49XC?= =?us-ascii?Q?BYSOiWqrQsaZm2pqolIOfnPqtQgYwaooj/cKsU4kmy++IZmFb9aPRHenNKkM?= =?us-ascii?Q?AzqgnaoDikDTi1B7kLvUTaGn3Lw6pCjqn1SlzuECDHlVJq7gchAXJr7tzRpw?= =?us-ascii?Q?KFKMFwEKjvZcAvX4xPQ77khaazBc0oabjOyvqcc0/1E6AS8PnJgEoS3mPNnB?= =?us-ascii?Q?cJ3ujMKrlBAKYxJvrA1crsdN89LAho/0WOb+0nI+AEcDf5BLb34I8qZ7+5IO?= =?us-ascii?Q?btUSJVfJsUM7DHGFYbRQALdy2J1h16PpxXkRwlDoD4k0zWCpDv5ayclWzb8v?= =?us-ascii?Q?XEnXKBLMk4ksF3hYJpLczuEaBGYFCA7I1ENtU51RbBanDGSdZxEk2D5dGVqd?= =?us-ascii?Q?YdLnhSMdNDzxWttGwgxdtyYMol62BvmryupM/0GhQhFuNjo0DK5bXSXxOM78?= =?us-ascii?Q?i6BEM2M3LgfzjUoosCo=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: 16 Oct 2025 10:42:44.1159 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 7e37ebc7-7a49-483c-c69f-08de0ca0bd5b 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-SJ1PEPF00001CDF.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SA3PR19MB7301 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMDE2MDA4MCBTYWx0ZWRfX9YEJBUW7nMvt LATYsp+2ME1V0iE/r2gyuIydUvHQarj13uqT+UYGC03R/myGWrZ9EktYEN/JHYuZs+l4tAhWLjz BnO+uxZoApHN5b87GZ1E20dskwXUkK2wpwL0seTAMrZpYyZL3TLHDugSczweOZoQ3kFDUqHLu5V d0zl7btt6x+uN/G88Qo8kIlNhE+cJxhKwZit5QSbZ8oBTqPDwJWIoAU4nvrRIuJDAvvwuNL12+j QfNO1fhL49NLHra8qwHNXRuXv8k/gET0z7MeiXPKPbVmLCFejuq8S8R5u2EZs5vL/vpWWw23fW6 ja3Q/rocfJK+F2h2YO/2gNQfhSYh2oR4akugkqRuovsVne9rdCHkJ7HecdPxkq5ELTCeY/SpUbc INzRZdT9qdSYno3D5H4RMuECgqTikA== X-Proofpoint-ORIG-GUID: Kdt0-2KI4k6C9RlIy_AoF34nFK-S-kO4 X-Authority-Analysis: v=2.4 cv=OJIqHCaB c=1 sm=1 tr=0 ts=68f0cc2b cx=c_pps a=YwNxXrBOkeX2Yvw65jHa0Q==: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=_YETvGvGxytoiswIzucA:9 X-Proofpoint-GUID: Kdt0-2KI4k6C9RlIy_AoF34nFK-S-kO4 X-Proofpoint-Spam-Reason: safe Content-Type: text/plain; charset="utf-8" Add two 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. Signed-off-by: Richard Fitzgerald --- include/sound/cs-amp-lib.h | 11 +++ sound/soc/codecs/cs-amp-lib.c | 122 ++++++++++++++++++++++++++++++++-- 2 files changed, 128 insertions(+), 5 deletions(-) diff --git a/include/sound/cs-amp-lib.h b/include/sound/cs-amp-lib.h index 43a87a39110c..e4df0736039a 100644 --- a/include/sound/cs-amp-lib.h +++ b/include/sound/cs-amp-lib.h @@ -47,10 +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); =20 +static inline u64 cs_amp_cal_target_u64(const struct cirrus_amp_cal_data *= data) +{ + return ((u64)data->calTarget[1] << 32) | data->calTarget[0]; +} + struct cs_amp_test_hooks { efi_status_t (*get_efi_variable)(efi_char16_t *name, efi_guid_t *guid, diff --git a/sound/soc/codecs/cs-amp-lib.c b/sound/soc/codecs/cs-amp-lib.c index 8434d5196107..b2509c5c0690 100644 --- a/sound/soc/codecs/cs-amp-lib.c +++ b/sound/soc/codecs/cs-amp-lib.c @@ -10,9 +10,11 @@ #include #include #include +#include #include #include #include +#include #include #include =20 @@ -46,6 +48,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 +85,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 +146,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 +204,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 +332,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) { --=20 2.47.3 From nobody Sat Feb 7 17:19:48 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 A22A0324B11; Thu, 16 Oct 2025 10:43:06 +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=1760611389; cv=fail; b=MSrDm2lozISiSFamS/MYsW/r48U60QyyrGj3Doz+wDA4t4hugkhuomnXlQvvkbDftWCcvnNmSOz2oj7oDmQ490nyE6TpuMcM6l1SvHmF1wkGrOzULyTKFYKzeV0XSQiUTxDeyTeQoLwFlBZfpWUwOcRz1DH3VGlOJ/XaRQboPsg= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760611389; c=relaxed/simple; bh=yNQzTz4LGiHjYITwEhjRllr45+edbbouQg4uiQygpIk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=mc/+6NqpJc44Rm/p9TAThdLr4Py3wS/jUzLjcgb+UULtz+/M+7qZheBfzSGZCxjmMDj4PTnkfhpCMwuArqf63QOln4fZHiR4tjlyX25doRztjMWrhBuB7GvG5d7RzK41mdPBI6loiFXtkbQrlez8RSvbYh2nQPlfmRLBIpPGC4U= 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=UaYccx2T; dkim=pass (1024-bit key) header.d=cirrus4.onmicrosoft.com header.i=@cirrus4.onmicrosoft.com header.b=reQFi77h; 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="UaYccx2T"; dkim=pass (1024-bit key) header.d=cirrus4.onmicrosoft.com header.i=@cirrus4.onmicrosoft.com header.b="reQFi77h" 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 59FLMCHR1728776; Thu, 16 Oct 2025 05:42:51 -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=c6ovHgj0CvjYXZ/cHJnhStqygCCRz5MepGwYornyhmk=; b= UaYccx2TPIK2ePRlHV7gKdcQCDlCkgrY3OqBkwZymnypDEhW5S1dIfHsGa8HUVGO +fwJ1DNxnpXvm+FMAnmccISPhCPYc9YRk2DJ+Pd68Eqn1E3h39MiFBn8fy0JMvaP O6azZdXuAx48gJFElQX6jxcerzDy3IUb9MaoUXF1A4Rar9TfazTS0ntttc2Mp0XT XOAKicjQpyop9DAfthZ+vQBx7q43SfKmdk3QXrc4a3+hZs8wMJ/Xw26vKfU9Qx/N L4Zg2dYdt1TlmU/LIwgV/ppfW8gdO+K7dlOpEq+x8VshH+es4ZwrVNOXkBlGwhuq wzA8cDLyPhzHmLMpSBgDRw== Received: from dm1pr04cu001.outbound.protection.outlook.com (mail-centralusazon11020128.outbound.protection.outlook.com [52.101.61.128]) by mx0b-001ae601.pphosted.com (PPS) with ESMTPS id 49sdb448a4-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Thu, 16 Oct 2025 05:42:51 -0500 (CDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=mdRakwj6cBVteX0pFbKUZjQ62Q4QNslgoRl89R2i7ys+LfT2ULyxnDlRftNR1bEfDIjxC+oiC1pkyuyzm0wssdyDzyrJafDT6/gFUdWxnKzXoWJ+/v5gN028snEVh4YdLjtyO1KLft79LTeq8d3L7lHQJC9g1qesY0UTmqEmSuZ9ViRtXzyRduIQebh612xQ01CEmg2YZWZPgZ3iqfdUMRn3a4FQFUqFvRUwaMeaeEIUJKv5wIAcrAMqhXgx9BpD1m9yNjJU4ltA3DsYMrQ4fac9865qaf5f+1hFKobikVW/IRl+fAboPjm0mypDxiOqjbtCReIjUiv21pR5IO1LDQ== 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=c6ovHgj0CvjYXZ/cHJnhStqygCCRz5MepGwYornyhmk=; b=YhcB19ct0j8j6QJ7+xBqMLCaLEBs/LyhfwYk/mf9Xglepxeo/LYbjlmWCBFMjWH2Kw8ouQWladzN8lV6DK5HxofYrElBWfiHFcDhpiAG4u/H21klgCdwMLAb4DgKdulKV2QALohmygJR62Ud+AesXPAf1RReFmsBJqOA2rgjauTpU30m7JkJvvBTzroWIq4tPk7MX+Ew/9pTFQsyKYCCyG72bIkyQrQE6f4zAQmxC591zdDTxePYVRlDIyTgKBEJcKDVHw47t7xWfZXCN2n8kJ8ugTOHIAn+7hPRVwFpSl32d8Ephxtzfw4P066Iqk6YZHqsH1THZ78q1sX65RawyQ== 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=c6ovHgj0CvjYXZ/cHJnhStqygCCRz5MepGwYornyhmk=; b=reQFi77hZWb/xvf2+DqA/0gPavd+BYiJB/Y6NEWMtwUTLSp0hBrnieLvD9y1epa2r/6cYIO8v/d/uJIn280zWRDporYgwsTwjUvfiguAWxNbfh26No8CTxEynA+qQYWNE0hiedtxQ/b3q383IF4EgOCwlbJiZep5NkZrCwYl5go= Received: from BN0PR03CA0038.namprd03.prod.outlook.com (2603:10b6:408:e7::13) by PH7PR19MB5797.namprd19.prod.outlook.com (2603:10b6:510:1d4::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9228.11; Thu, 16 Oct 2025 10:42:44 +0000 Received: from MN1PEPF0000F0DF.namprd04.prod.outlook.com (2603:10b6:408:e7:cafe::31) by BN0PR03CA0038.outlook.office365.com (2603:10b6:408:e7::13) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9228.11 via Frontend Transport; Thu, 16 Oct 2025 10:42:44 +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 MN1PEPF0000F0DF.mail.protection.outlook.com (10.167.242.37) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9228.7 via Frontend Transport; Thu, 16 Oct 2025 10:42:43 +0000 Received: from ediswmail9.ad.cirrus.com (ediswmail9.ad.cirrus.com [198.61.86.93]) by edirelay1.ad.cirrus.com (Postfix) with ESMTPS id D093E406553; Thu, 16 Oct 2025 10:42:42 +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 BA8AC820249; Thu, 16 Oct 2025 10:42:42 +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 03/11] ASoC: cs35l56: Add common code for factory calibration Date: Thu, 16 Oct 2025 11:42:34 +0100 Message-ID: <20251016104242.157325-4-rf@opensource.cirrus.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251016104242.157325-1-rf@opensource.cirrus.com> References: <20251016104242.157325-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: MN1PEPF0000F0DF:EE_|PH7PR19MB5797:EE_ X-MS-Office365-Filtering-Correlation-Id: 22f160bb-171f-48eb-2cae-08de0ca0bd03 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|82310400026|36860700013|376014|61400799027; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?KSby2rHIkKMi+rtTQHgK6WEF2fTxANgyAWf9OkN9Gm2EIco/xgUjvEjLdqZ5?= =?us-ascii?Q?IVoSlMaYSflzNueMZDUgmsbqgySVGWMAeHbz/zHmU5h1GBMA1TbsuqgCMt4b?= =?us-ascii?Q?JrqO9U0mR7BpLpfeFmX0E/AYgp8zIIGKJ1cxjV3ywnzsoo2Tyy95afYBwdNc?= =?us-ascii?Q?G4tXrnu4Bun1fSOcG78/cnMki63fqKzLGIzrSRj1wx+Nbaa3nE4wkAELiAg2?= =?us-ascii?Q?mKqYLwJUQfV78trjoLkG7RTcclpa7FeuSehrVoweL9KmK/HFw3SbAjrHdqSP?= =?us-ascii?Q?YVD+nlVb9An6zOjT8WD1fAA0qETlQA/VeINEZfIpo7rJ88Ze3D4r7SYIfPyL?= =?us-ascii?Q?3YOQ+gp1eGT7WJFPz65fLn7DB6tUZLEJl4iFhZ0gxoejdFadduutxA/Wb0IL?= =?us-ascii?Q?eqT5WWg/PJgWbo+H4Id3Nnomjgt4fnbu1sgGQlBm7ozr7pdWBnYUN1lS1VSa?= =?us-ascii?Q?pPjwiOSe/px2m4+MgWppoGl0qDBvWqZmNYOqVaBJPlI0SVQcvH3LigxkEez8?= =?us-ascii?Q?qRXM7irtfUbdawIl80ext73O6i+/yzxdM1A7ukKzNlRMT6vzM/C/zMWX1G3x?= =?us-ascii?Q?SPWt/Y0NWrTq4WYqqXq/zE+v74Dnp/QWgr2viDUWjWqg9NSfh18vpNzXT86E?= =?us-ascii?Q?QL1f/5C+BUMNsPM6fWHoRI2DqIeKy/hSSgZAaHpmQvnj9ik4Yy/pABi9Scrl?= =?us-ascii?Q?tTVac8DDcblDoBhjrTy5t5fQIi/k4L7L+maKBu053xxzyT99LafkeuQjr50H?= =?us-ascii?Q?uRgAlWyJNavPAGdsm7MxMWGdjuMeK6OfQ7BGMWBDocxd6QEm3He6ukto+Yst?= =?us-ascii?Q?7CcCydSULFPF/oRiBanoLiaRZuOZURE3TJWc5oAQ3NyJx8+XxoDWN4Kg0Wqg?= =?us-ascii?Q?mco1RxUCn0zJuYgpu8n80Meh7FMXP15qksVnwp5rdCVzQmQTKxt91iYqB4Dq?= =?us-ascii?Q?ZcoiS1GQiDnsmm5awNpCEj8unQCk8sJ6UrnN9Q4yuEn1p/hIbncLeQ0WHuU3?= =?us-ascii?Q?uoj1ocHelpRSo69sNfmbEmAJSe+CRfgRm/p6UIITMuSxwmLuTZ+WZut/P0SR?= =?us-ascii?Q?W72zpy3Kk5HJNIG0H3+hTfbyitlUgj55fWHqcLL9kPcNoLJaRgV+enVD2TCz?= =?us-ascii?Q?uIXEG//zsBuOL1McTmjvDCg0DslxZ23r1IsHEUhCdD+TUbDQY6YsbbrXdx7w?= =?us-ascii?Q?Po3r/rAR2RAmbzGzLScUY5Cpg4M1osMYbS/g5cHk7bVl8u9g0fRZ6C7kp2mv?= =?us-ascii?Q?eviFobqWsJa53flwVRCRqyKyp/aMztr/wmzbWTMmOT3yGTulo5hYowfu2lqy?= =?us-ascii?Q?4eG4BPzDF9lQsrowQI0Sk7cKKorqmxPKruUpgnfKDs3lLOnG5D4u17ycUYYI?= =?us-ascii?Q?2t/UJR+2sw12xbTAiVdQoZVBnE6kmy4Nm7eRjBlQmv4wh9AAa5tNBpT3e+d7?= =?us-ascii?Q?mE1WnJloFxY5ZptE9do8KiW3BE9iLIps7XObQMKZ1oEqrmt0EQ1DW7/TnLTO?= =?us-ascii?Q?YT2FmLiA4AtfQGbrejJRmOLIXm20U3wEiUxyo7jb7RoVUCVyGog6tW4m7Who?= =?us-ascii?Q?YRUci4/FWeIE8lQmnIk=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)(36860700013)(376014)(61400799027);DIR:OUT;SFP:1102; X-OriginatorOrg: opensource.cirrus.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 16 Oct 2025 10:42:43.6516 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 22f160bb-171f-48eb-2cae-08de0ca0bd03 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-MN1PEPF0000F0DF.namprd04.prod.outlook.com X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH7PR19MB5797 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMDE2MDA4MCBTYWx0ZWRfXxqx63oNBHkLF lgeC91RXdUV8oKdAWjaZq7qikTlF6LnrxWj9yw6qdMdgH8042B0xcfipPtj/MqkOE8D3NsyMZnb yOpRXh2VIWP+ARSq0XLVsCwF+uyDdiI54KUSSCcYGp5wWwB05wanVO0cScE8k2MsZn+Io5ar/cp SAWCDDbAGrmuJHEglzyvcgTAzFVd8KEBd54yu2DLEgRH/X4ro1RFGftXCA/Aiz0Pea8gOgtFWEf KJhjrl8VfvZ9uu3URdozqVbnRHVwQh01egoRmwFsD9wKaOEP6lGQOKh2aoWoc3Fu1816H0DTEla wGcZEVJilpRTNvoTrT5JnYnKMSb+qO9xGdfjFfJZQdWkVk9KKeOxUhOlsf7IW347+Q9L3nVwJGj NjCqWZW70P1LrJfcsNhGlgk4t8Ij+w== X-Proofpoint-GUID: K7Q-RFzC8KH8zokxdjHpjhWny80SPuRK X-Authority-Analysis: v=2.4 cv=PPICOPqC c=1 sm=1 tr=0 ts=68f0cc2b cx=c_pps a=8h7WK4dQWB09CNKj11a7yw==: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=vH_VZnYPvUgQ1igPj3EA:9 X-Proofpoint-ORIG-GUID: K7Q-RFzC8KH8zokxdjHpjhWny80SPuRK 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 sysfs handlers for three sysfs files used to start factory calibration and read the results. Sysfs is used here so that access will be restricted. These are mainly intended to be used by manufacturers and in service centres after a repair. It is not something that a normal user should ever touch. Calibration affects the matching of the amp hardware to the external speakers. If not done correctly (either accidentally or maliciously) it can cause the speakers to be under-protected. The PC manufacturer's tunings can limit the allowed range of a calibration result but some speakers have very wide manufacturing tolerances, so the allowed range could be wide. This is not a full implementation of sysfs 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 sysfs 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 sysfs 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). As a precaution cal_data can only be written if the driver does not already have valid calibration. 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 --- include/sound/cs35l56.h | 18 +++ sound/soc/codecs/Kconfig | 3 + sound/soc/codecs/cs35l56-shared.c | 253 +++++++++++++++++++++++++++++- 3 files changed, 269 insertions(+), 5 deletions(-) diff --git a/include/sound/cs35l56.h b/include/sound/cs35l56.h index ec9b1072d6be..4ed738615021 100644 --- a/include/sound/cs35l56.h +++ b/include/sound/cs35l56.h @@ -62,6 +62,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 +179,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 +248,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 +270,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 @@ -294,6 +303,7 @@ struct cs35l56_fw_reg { struct cs35l56_base { struct device *dev; struct regmap *regmap; + struct cs_dsp *dsp; int irq; struct mutex irq_lock; u8 type; @@ -359,6 +369,14 @@ 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_sysfs_store(struct cs35l56_base *cs35l56_base, + const char *buf, size_t count); +ssize_t cs35l56_cal_ambient_sysfs_store(struct cs35l56_base *cs35l56_base, + const char *buf, size_t count); +ssize_t cs35l56_cal_data_sysfs_read(struct cs35l56_base *cs35l56_base, + char *buf, loff_t pos, size_t count); +ssize_t cs35l56_cal_data_sysfs_write(struct cs35l56_base *cs35l56_base, + const char *buf, loff_t pos, size_t count); 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..5917bf5a72f8 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_SYSFS_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..dc6e49e3421a 100644 --- a/sound/soc/codecs/cs35l56-shared.c +++ b/sound/soc/codecs/cs35l56-shared.c @@ -6,11 +6,15 @@ // Cirrus Logic International Semiconductor Ltd. =20 #include +#include #include #include #include #include #include +#include +#include +#include #include #include =20 @@ -206,6 +210,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 +269,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 +732,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 +745,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 +854,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 +959,232 @@ 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_sysfs_store(struct cs35l56_base *cs35l56_base, + const char *buf, size_t count) +{ + static const char * const options[] =3D { "factory" }; + int ret; + + if (!IS_ENABLED(CONFIG_SND_SOC_CS35L56_CAL_SYSFS_COMMON)) + return -ENXIO; + + 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_sysfs_store, "SND_SOC_CS35L56_SHARE= D"); + +ssize_t cs35l56_cal_ambient_sysfs_store(struct cs35l56_base *cs35l56_base, + const char *buf, size_t count) +{ + unsigned long val; + int ret; + + if (!IS_ENABLED(CONFIG_SND_SOC_CS35L56_CAL_SYSFS_COMMON)) + return -ENXIO; + + ret =3D pm_runtime_resume_and_get(cs35l56_base->dev); + if (ret) + return ret; + + ret =3D kstrtoul(buf, 10, &val); + if (ret) { + ret =3D -ENXIO; + 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_sysfs_store, "SND_SOC_CS35L56_SHA= RED"); + +ssize_t cs35l56_cal_data_sysfs_read(struct cs35l56_base *cs35l56_base, + char *buf, loff_t pos, size_t count) +{ + if (!IS_ENABLED(CONFIG_SND_SOC_CS35L56_CAL_SYSFS_COMMON)) + return -ENXIO; + + if (!cs35l56_base->cal_data_valid) + return 0; + + return memory_read_from_buffer(buf, count, &pos, &cs35l56_base->cal_data, + sizeof(cs35l56_base->cal_data)); +} +EXPORT_SYMBOL_NS_GPL(cs35l56_cal_data_sysfs_read, "SND_SOC_CS35L56_SHARED"= ); + +ssize_t cs35l56_cal_data_sysfs_write(struct cs35l56_base *cs35l56_base, + const char *buf, loff_t pos, size_t count) +{ + const struct cirrus_amp_cal_data *cal_data =3D (const void *)buf; + int ret; + + if (!IS_ENABLED(CONFIG_SND_SOC_CS35L56_CAL_SYSFS_COMMON)) + return -ENXIO; + + if (count !=3D sizeof(*cal_data)) + return -EMSGSIZE; + + ret =3D cs35l56_stash_calibration(cs35l56_base, cal_data); + if (ret) + return ret; + + return count; +} +EXPORT_SYMBOL_NS_GPL(cs35l56_cal_data_sysfs_write, "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 Sat Feb 7 17:19:48 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 DF13632548C; Thu, 16 Oct 2025 10:43:05 +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=1760611390; cv=fail; b=qB9hwHkgP5/QDrE7ogvGDJmdLYeENACmHIV0Hd21MvWICLUlztZeM5n2/XXKQY7A91JN+QAHb7ZiuqUt8xsBZETOHzIWx+DVLXH1WamXamQA3gVJlJ2t99AIRbskISVfTF2Q4TjiZAaOeQe+nhZc5NJRv1EH67FGwm/+XM63AzI= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760611390; c=relaxed/simple; bh=xe9isHURiGCSCnrPZv1iNkKHBJbtBslRmrIgkwQwQc8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Er8DZFJVBCXok2VuEt0dbNUmS8AwRKmTVwmY898lFWrGBprZA6YbK9uPb88JzGRzq8kjCnWvvAJKVRvguVbizIrnpB7kzPfmKG6sz7xiK/jAA+2O8D/x+mw1fuTRFIjCjri19hYY6QoRN6k3Hc4LClp41i+F6NCLDiAUF8EgWd4= 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=dEc3yf4N; dkim=pass (1024-bit key) header.d=cirrus4.onmicrosoft.com header.i=@cirrus4.onmicrosoft.com header.b=JoiNbbhT; 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="dEc3yf4N"; dkim=pass (1024-bit key) header.d=cirrus4.onmicrosoft.com header.i=@cirrus4.onmicrosoft.com header.b="JoiNbbhT" 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 59G9oCCV648147; Thu, 16 Oct 2025 05:42:51 -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=K2q66aE5vwdHFLLDQ2AzsfwIuxcNDVy0+9Dpe54jNJI=; b= dEc3yf4NwAdEY02GidkHAgzGMPbq6hAQW9eH9J+offwNfxNwlzkREx8FkehEqew8 VQ+CJE+mVHL/ZGl28wn4BtGZ5SppUaxN2hHG/zXniuGZYm83TVyrpOUziEWjb/QK YdhUDJx++f5V5ELejfQW/CSUC1Lrz0hxoz5c6KqYFYxC01upncUHlsgBvizTZObz wLV/Ao5OVPk7AgGlRdVUHMPSJv7IDscdUPNdxt53mqJeVDUB8UI5l+5Hl6ildsOK Fp0deEQEKz0rNMvRpZCLA/+DXUKqvnqRG/Joc1Jg3wK7AJ2KnbfQj3J+Angh0GsT Qgskb85FRFNDWFdXvDGF8Q== Received: from ph8pr06cu001.outbound.protection.outlook.com (mail-westus3azon11022133.outbound.protection.outlook.com [40.107.209.133]) by mx0b-001ae601.pphosted.com (PPS) with ESMTPS id 49sdb448a3-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Thu, 16 Oct 2025 05:42:51 -0500 (CDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=Vq7bC3pA+8l1Z6ZlacNQKBhwh3ovn1Q81l+F80yRIUGHQzAryPczOSF0PLujvPklv5aiIsf7I0ogg8Im9HrnfTFEQWPWmERDAatAnSrg9p+C0q3RlwwA9nMT4HD9Yf/fBenHBppxmFbMeVu27V0vPgOPO/nnlUknIkYVL/qeKse9/dUtBnYXdgR7Rp0y0vp9k09NqPfUYFjzdzxu/KRkuGthrLFxuiGU3AKAEUJMZMkC8eiQ+xU5f4yRHEpUKniHVD08+VcswSGeYS6ch8yw9ad9RwoSofwKluBtCC7ZsS8CU8I9YxAlv0oE6LMoC4vvN4HYmap5fpusvpsq0YF2jA== 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=K2q66aE5vwdHFLLDQ2AzsfwIuxcNDVy0+9Dpe54jNJI=; b=SYkn3oXawKsL2IXTsHTupMrDDiQvQ9+fTL3+H9nSALVMqdCgXtl8EcCZUB1vazWaf15mN/DwlVAJP7U0BmqkKiCMAPjskpLiOsGCLZ45RVckeqrFRXfA3CUyOm3z2mBebBjz3T6SX3h+E4z6KQwVS04nGOBnFyux/nhMg0dK0Bx/2ovGsRMcgmiPFK87oZA8lnHxCtCmah84tuQHvaHWtjPABY0svNshmlBMVdoxfMQ6Qay29KF4qoYBO3EPnFYoi93jiChYl95OAXk7qnjohbjQ3eAhm/2YTj3WNfsLKxKr2lSLQvLhPm0MjSCG1XUga7jIKoCd4yI934EHZxwYvA== 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=K2q66aE5vwdHFLLDQ2AzsfwIuxcNDVy0+9Dpe54jNJI=; b=JoiNbbhTEVpqzUZ6ICvMuOsAI5BD0OQSHKaWAk+FAVNhv563RrD6KC06z6HiDhUecxCaAd4kcVDEwceVwavwJVsWVzAe0XjbHCmsIrnZUYEEaSFNkrel1DUm3jpoE6hc4P9Xg6t0zA2gnkN0CljIwRahLLYrLMsoz6hkO4zdcJ0= Received: from BN0PR03CA0037.namprd03.prod.outlook.com (2603:10b6:408:e7::12) by DS7PR19MB6023.namprd19.prod.outlook.com (2603:10b6:8:82::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9228.13; Thu, 16 Oct 2025 10:42:44 +0000 Received: from MN1PEPF0000F0DF.namprd04.prod.outlook.com (2603:10b6:408:e7:cafe::66) by BN0PR03CA0037.outlook.office365.com (2603:10b6:408:e7::12) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9228.11 via Frontend Transport; Thu, 16 Oct 2025 10:42:44 +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 MN1PEPF0000F0DF.mail.protection.outlook.com (10.167.242.37) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9228.7 via Frontend Transport; Thu, 16 Oct 2025 10:42:43 +0000 Received: from ediswmail9.ad.cirrus.com (ediswmail9.ad.cirrus.com [198.61.86.93]) by edirelay1.ad.cirrus.com (Postfix) with ESMTPS id DB1D8406555; Thu, 16 Oct 2025 10:42:42 +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 BED37822542; Thu, 16 Oct 2025 10:42:42 +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 04/11] ASoC: cs35l56: Create sysfs files for factory calibration Date: Thu, 16 Oct 2025 11:42:35 +0100 Message-ID: <20251016104242.157325-5-rf@opensource.cirrus.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251016104242.157325-1-rf@opensource.cirrus.com> References: <20251016104242.157325-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: MN1PEPF0000F0DF:EE_|DS7PR19MB6023:EE_ X-MS-Office365-Filtering-Correlation-Id: d74a6c52-e409-41bb-17c3-08de0ca0bd0e X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|36860700013|61400799027|82310400026|376014; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?POfHs+Tf2ljNUdNXrTsP3y1uDXE03xI1dBPg1VZTkJiYUmm69iXh5i8S6ZdT?= =?us-ascii?Q?BBH/eqjZIW5+fY8Nrb/HWMS1otTaJi8zS2RKP3LiWI2jYKFN6P0mAb6gFlZi?= =?us-ascii?Q?0xkSBQJqBaUFZyGNTKK1Ln1S+T3tScPGE9PIlFoT5bUxxR7GKLzFI2bQTd51?= =?us-ascii?Q?5oXGL4aH5ZNmUfRfRKVtdUXxyumfLcKZnIJJnQhI1JRpGwyHHNBTOqfCHhce?= =?us-ascii?Q?LodiagZZ3+gI3r/ZZK2F/gXpf4SpMqnYCJYUCA0PSeZO0CUdNUjwUwidV+J1?= =?us-ascii?Q?FIaIzLhDWOAS3rZ6URG8fbmc9wNiDM1w6k84x59MvdcTveY4QHyyXClr/62F?= =?us-ascii?Q?JTXcZcfhdpGNR6j9FY1qlYYd0znqAqfsSDMv3Y/p6P+U9w26tuPo9fZ2nXKl?= =?us-ascii?Q?N04Oct0UqKVOqCiY5yNgFxqo2u4NVbrxQQWGhT6CKHAqeZHrkkG9PL7WL5qb?= =?us-ascii?Q?+RO8K2quieYDKzfEDphHWcVqCl9ejuZiyobnVU2YygXy+tOtndDs+IK8IfIw?= =?us-ascii?Q?alNVV9fOP9zPO3rOidBVwwqbsk/oP7dDxpraAsmRm5L4o6C8wT7aSL0VY61X?= =?us-ascii?Q?39ZgXqm5Oz7TECwIq5vPszzT3Qe8MrmcoUyfVw2IKLAFsAi7ujXGRJ5TETrl?= =?us-ascii?Q?WyNeZPwSYPbReKIFAyFI9XcAw+Djs6mt1ahj4ZSUSxm9/4nbpFS8oWL9f7yQ?= =?us-ascii?Q?n2JpDkPbgE7bw2n2SB+VjrT65cCVNvAlJw7nEffWQj4Joq1SIQf0fwEWkZzO?= =?us-ascii?Q?5sDPjQ8ORag30zw09D2hNqmLniYKjXIm+l/Q65BZQXHqRxlQxU+BGH515w9e?= =?us-ascii?Q?jrAGqQD/lHEyfh2VPa0p+Q7qUfCjbrYdJVL3gUgvV9WTveRAzzfEyNSNb3mQ?= =?us-ascii?Q?CsbuNRAgY5HJ6eumw8sWFo4KIm5TSf1J+0W8z74cho5Ou9TixAfM/dmTfwsv?= =?us-ascii?Q?J6zfXk1xHNNK/Sokti96qAMtNdj8lCneu6G+F6jIny34GPwna1V3+uHiJ7Un?= =?us-ascii?Q?wOFnqoXtLaVDqUSTqC/3hgKcyCLnBr1Mx/G/FkoOH8dyyRpYOkjYIZMnJ8Cm?= =?us-ascii?Q?+1m7OjOq++dmEg2woY8OE5tuz8QPME259Y4x2jHPUo0RSMOVTmb4p8i8zCMX?= =?us-ascii?Q?FYxW2uiw/WHWULoHPeOxVhiCdjH4lwRbYNEnmw+aD7zyRxTcV06gdz67M/wo?= =?us-ascii?Q?biRZ+sTyWEB0Ko051m55IwW+W8XdFGB5ROrDLtFh0AgdQk2tADMQPMeBn1Sn?= =?us-ascii?Q?m81SmVF52j84tq2Iueg+QkU10oX+tYZIYUeV1k7oRD7de6CePyLPhjHMbBM5?= =?us-ascii?Q?iWKmNsOGw/QYecu5JXgR8Aqu6/muskSNfZTnA/5qHwA9261T3N/LocXgRMHD?= =?us-ascii?Q?fltIXJxY23uglYlR3A17zDq5TYS7fCw7tbcuR3LGMIfZ2xuKWtIatH0LaqFE?= =?us-ascii?Q?U/WijqiaKR7l4f+x8cA6sJxsjpeHY573X2+Q8iBkfCeVgXJTEepNPyDHPSSw?= =?us-ascii?Q?zBQITcvtTp+rOavIEaIZY3eEc4JHbMWKaPjC0jx8KdBIW6Wp3A4R4Ey2q5vD?= =?us-ascii?Q?hZ8PfPSlxDBdpMS+uHM=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)(61400799027)(82310400026)(376014);DIR:OUT;SFP:1102; X-OriginatorOrg: opensource.cirrus.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 16 Oct 2025 10:42:43.7233 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: d74a6c52-e409-41bb-17c3-08de0ca0bd0e 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-MN1PEPF0000F0DF.namprd04.prod.outlook.com X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DS7PR19MB6023 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMDE2MDA4MCBTYWx0ZWRfXyHo2TYCt4yFJ zZMULgZ9EpZpE1LiZNflcNFxtytzrJAt4i6/6emoh8fQkdw2xbzRdrrQ82kVxnBJNOV4E45sWTj g/kxOpp4UrhdsPkNmlIEnh8JSY7fPpPlVCZPZZR2r8HYoSetofKpse70BDbuuWkSIILafrDUuD+ n+FdTSvgm9/i74J0rjOgjeAUKrqCQQVTA0iraQLwxNeEual7Q0iDtxmV5lpCShCu0MqC4624UYC 5q8aphzfygf0faiwjg/f1+4Pkduc+9GB++dUj3dqiSf5ttwx40aMWOuDZqhHVujrCyQk4cftDGc cvBgDhfMDgBTvaNzSRzxeOsf44KzfEc1uIeo5Y8wT255PS1Iz7Z/0yEWt8cHA4hfVdGefoH/wJx yGimkRNesW3lLykNInSm+KigG5iC/g== X-Proofpoint-GUID: 0VUiJAzeQ0-YCXRmZIMe9yK3WvXKVQ-u X-Authority-Analysis: v=2.4 cv=PPICOPqC c=1 sm=1 tr=0 ts=68f0cc2b cx=c_pps a=o+9IzLN2JPavfcgUIASn6g==: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=pkDbqoULcYAe4JYMWOoA:9 X-Proofpoint-ORIG-GUID: 0VUiJAzeQ0-YCXRmZIMe9yK3WvXKVQ-u X-Proofpoint-Spam-Reason: safe Content-Type: text/plain; charset="utf-8" Create sysfs 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 sysfs files. Sysfs is used here to restrict access to the factory calibration. It is only intended to be used during manufacture. It is not something that a normal user should ever touch. Calibration affects the matching of the amp hardware to the external speakers. If not done correctly it can cause the speakers to be under-protected. 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 --- sound/soc/codecs/Kconfig | 15 +++ sound/soc/codecs/cs35l56.c | 182 +++++++++++++++++++++++++++++++++++++ 2 files changed, 197 insertions(+) diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 5917bf5a72f8..4bb57223ef82 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_SYSFS_COMMON bool =20 +menu "CS35L56 driver options" + depends on SND_SOC_CS35L56 + +config SND_SOC_CS35L56_CAL_SYSFS + bool "CS35L56 create sysfs for factory calibration" + default N + select SND_SOC_CS35L56_CAL_SYSFS_COMMON + help + Create sysfs entries used during factory-line manufacture + for factory calibration. + This is not needed for normal use. + + 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..930991dd4b6f 100644 --- a/sound/soc/codecs/cs35l56.c +++ b/sound/soc/codecs/cs35l56.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -22,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -250,6 +252,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 +290,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 +879,175 @@ 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 calibrate_store(struct device *dev, struct device_attribute= *attr, + const char *buf, size_t count) +{ + struct cs35l56_private *cs35l56 =3D dev_get_drvdata(dev); + 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_sysfs_store(&cs35l56->base, buf, count); + snd_soc_dapm_mutex_unlock(dapm); + + cs35l56_power_down_after_cal(cs35l56); + + return ret; +} + +static ssize_t cal_temperature_store(struct device *dev, struct device_att= ribute *attr, + const char *buf, size_t count) +{ + struct cs35l56_private *cs35l56 =3D dev_get_drvdata(dev); + 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_sysfs_store(&cs35l56->base, buf, count); + cs35l56_power_down_after_cal(cs35l56); + + return ret; +} + +static ssize_t cal_data_read(struct file *filp, struct kobject *kobj, + const struct bin_attribute *battr, char *buf, loff_t pos, + size_t count) +{ + struct cs35l56_private *cs35l56 =3D dev_get_drvdata(kobj_to_dev(kobj)); + 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_sysfs_read(&cs35l56->base, buf, pos, count); + 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 cal_data_write(struct file *filp, struct kobject *kobj, + const struct bin_attribute *battr, char *buf, loff_t pos, + size_t count) +{ + struct cs35l56_private *cs35l56 =3D dev_get_drvdata(kobj_to_dev(kobj)); + int ret; + + ret =3D cs35l56_cal_data_sysfs_write(&cs35l56->base, buf, pos, count); + 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 DEVICE_ATTR_WO(calibrate); +static const DEVICE_ATTR_WO(cal_temperature); +static const BIN_ATTR_RW(cal_data, sizeof_field(struct cs35l56_base, cal_d= ata)); + +static const struct attribute *cs35l56_cal_attributes[] =3D { + &dev_attr_calibrate.attr, + &dev_attr_cal_temperature.attr, + NULL +}; + +static void cs35l56_create_calibration_sysfs(struct cs35l56_private *cs35l= 56) +{ + struct device *dev =3D cs35l56->base.dev; + int ret; + + if (!IS_ENABLED(CONFIG_SND_SOC_CS35L56_CAL_SYSFS)) + return; + + ret =3D sysfs_create_files(&dev->kobj, cs35l56_cal_attributes); + if (ret) + goto err; + + ret =3D sysfs_create_bin_file(&dev->kobj, &bin_attr_cal_data); + if (ret) + goto err; + + return; +err: + dev_err_probe(dev, ret, "Failed creating calibration sysfs\n"); +} + +static void cs35l56_remove_calibration_sysfs(struct cs35l56_private *cs35l= 56) +{ + struct device *dev =3D cs35l56->base.dev; + + if (!IS_ENABLED(CONFIG_SND_SOC_CS35L56_CAL_SYSFS)) + return; + + sysfs_remove_files(&dev->kobj, cs35l56_cal_attributes); + sysfs_remove_bin_file(&dev->kobj, &bin_attr_cal_data); +} + static int cs35l56_set_fw_suffix(struct cs35l56_private *cs35l56) { if (cs35l56->dsp.fwf_suffix) @@ -971,6 +1145,12 @@ 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; + + cs35l56_create_calibration_sysfs(cs35l56); + queue_work(cs35l56->dsp_wq, &cs35l56->dsp_work); =20 return 0; @@ -982,6 +1162,8 @@ static void cs35l56_component_remove(struct snd_soc_co= mponent *component) =20 cancel_work_sync(&cs35l56->dsp_work); =20 + cs35l56_remove_calibration_sysfs(cs35l56); + if (cs35l56->dsp.cs_dsp.booted) wm_adsp_power_down(&cs35l56->dsp); =20 --=20 2.47.3 From nobody Sat Feb 7 17:19:48 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 C43202DA769; Thu, 16 Oct 2025 10:43:03 +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=1760611386; cv=fail; b=otI9hwK+lwJCMRbouoD730hQUQztItShdXvFGvcGUq0UnAlSUlots6rGEZF5+PZ88pjUJDNsCbzNwIeBVnZJCFg3jcyyzv9WcPgLOcHN1v1mhACjz7hTSULt8SFAjRgjiRNUq1/7XxwlxQ1jInD1dSeLv4zR2HqOQVHOg355Hj0= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760611386; c=relaxed/simple; bh=pFb+S0bm5x1nsJhn74dfU4At8/rQKj8D/HFWL5MV+qU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=dKVZFLJ+wWJdAECzqm6IG36/hujmyzJ129pXePRm3joA9xV+TRb6H182ucFia7hDAtg2aQYm8ecMU57682GmRRjYAINq7ql8LHWnK5Oa7U4u7WI0Hus0knMMrwvTP3eoddsKRH14/ajv1VEY7o+th3acBsy8Vjn6p6qYy5kd/uQ= 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=kBksV6Zz; dkim=pass (1024-bit key) header.d=cirrus4.onmicrosoft.com header.i=@cirrus4.onmicrosoft.com header.b=xQWLzD1C; 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="kBksV6Zz"; dkim=pass (1024-bit key) header.d=cirrus4.onmicrosoft.com header.i=@cirrus4.onmicrosoft.com header.b="xQWLzD1C" 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 59G9oCCW648147; Thu, 16 Oct 2025 05:42:53 -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=eigMgXC3mmB2bVkc38tlRn7apsQxJ723irr63EP0M2o=; b= kBksV6ZzmIiCKh+Pz+hAzRhaClvHQ32onZ3R2e6Ds7926tKcevnQ48+EmdlG0Rx/ LmHgLwkLm9yqDJB+bufjhBuQER6wUh8qb8wf6iw/k83b1NIBR6Z7nWdrsaMU/hRl Fvxin+UG2VtNA3WGx6Z5OYNhczMD7m11/O9T/Wen4QE4E9eiAcZkMFfBVOMDP8no YOB4ebGwFiOjGVTFBwXXWnP6fLA0ggSN7Zl5U4WLD8WDA4SALUFqsENpSPNyLeKK Wrf/ZOLdPGvkCijGbyY3QqNCUjugyV/DTyyHKxV51ImDWw6j0OmXo0mRlaOndtpO vswlIQk5tqSwtG7Zgn45vw== Received: from dm5pr21cu001.outbound.protection.outlook.com (mail-centralusazon11021124.outbound.protection.outlook.com [52.101.62.124]) by mx0b-001ae601.pphosted.com (PPS) with ESMTPS id 49sdb448a6-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Thu, 16 Oct 2025 05:42:53 -0500 (CDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=aPhTzKS+AU5dFnUj5oaonuo9wtyAEAVnX9ujlAY3mnGaDxrFPg7WqdNkNHQOdBwFaVcn6cFFR/7edhZswLe5XmdnMhnVoxApMRyGspgsL6y8DmG6Aaf+tYjbRWpMeMYnpl/2eyIijYgsxWiqRaJmey4aMOjsct8jUtmoHu73KuRhIkf2uadSU/7On0vh04tlXLq6D2wD7DZWwHjtpgsjDq5etb0hAkSJT9WLSH9zjTdf/IitDmKa995e81m05Ey4KJt5QSTCuqczqQ1qAxiKjVlXOp1VmCR5aA4TdiOSzZ54rqVNJVhMfOQ3im2GC7kfzUevaN6jkQhBMatFj/uklA== 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=eigMgXC3mmB2bVkc38tlRn7apsQxJ723irr63EP0M2o=; b=sMF9fHYe/8ZPJarZE81fIqYKZMZyAkOhb233PuXuAtA4MuthanHxycjBoX7gMUKCOXNeEXnaKC8E9r8u0BusUva0K5R0MyVIO14dxWqLCz4XS/9FGOyW+Z6daxiRDTFoXU221ZTa2VkfCkrxDHhRD0sBChyvh/XEG22cFr/Ze585ptmGYsqVLarQRzdQFNnDPvuNvih6/FwlHPbJ1VgxD0tt+rorzYnlUZ2C12r0mvFc70XRGEbBEc+IRbfc5c1wx2flG1fQplhI+9jb7KBr/rP2Zct0x1+EETYq+M4yHpDOn2sR/hm9vj1lbsJqwGP+3MpSIkzHExFldTOg2zHoDA== 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=eigMgXC3mmB2bVkc38tlRn7apsQxJ723irr63EP0M2o=; b=xQWLzD1CkzqsTLsPA3s5OKMdJEyzLL6Yjxyet5MYMZOXir5b+oPz5bBpqAeqn4WcuxS+0FC2l6W+fc1Wvu8boiM5qUng9EYLXZ/Sl703B6IJeJElH1fapzcnZfzZGcr+cOFoGxfuHchQlbWKk5iIpvwbvM4QPwPl4pXgpn4cgcA= Received: from BYAPR06CA0005.namprd06.prod.outlook.com (2603:10b6:a03:d4::18) by DM8PR19MB5288.namprd19.prod.outlook.com (2603:10b6:8:6::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9228.12; Thu, 16 Oct 2025 10:42:48 +0000 Received: from SJ1PEPF00001CE1.namprd05.prod.outlook.com (2603:10b6:a03:d4:cafe::14) by BYAPR06CA0005.outlook.office365.com (2603:10b6:a03:d4::18) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9228.11 via Frontend Transport; Thu, 16 Oct 2025 10:42:47 +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 SJ1PEPF00001CE1.mail.protection.outlook.com (10.167.242.9) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9228.7 via Frontend Transport; Thu, 16 Oct 2025 10:42:46 +0000 Received: from ediswmail9.ad.cirrus.com (ediswmail9.ad.cirrus.com [198.61.86.93]) by edirelay1.ad.cirrus.com (Postfix) with ESMTPS id DDE1D406556; Thu, 16 Oct 2025 10:42:42 +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 C30A4822540; Thu, 16 Oct 2025 10:42:42 +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 05/11] ALSA: hda/cs35l56: Create sysfs files for factory calibration Date: Thu, 16 Oct 2025 11:42:36 +0100 Message-ID: <20251016104242.157325-6-rf@opensource.cirrus.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251016104242.157325-1-rf@opensource.cirrus.com> References: <20251016104242.157325-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: SJ1PEPF00001CE1:EE_|DM8PR19MB5288:EE_ X-MS-Office365-Filtering-Correlation-Id: 87eb3ff2-4678-434f-ca86-08de0ca0bead 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?IZfWoRn7aql1oCXl8SmCChZD4Wqy4ItqcIEq1tzEB6ZMPW41VKrsTZnvaFpI?= =?us-ascii?Q?qqSm6ceHmL2Y0URdfHmg6P9pz54amt26B3soobagiNwlQ71YzYdbPRo9zSvc?= =?us-ascii?Q?4I2yNEAolmMrWrNLEQnx64oZWNka3DlMPdEZl1sBQN9UqB4BqJXQXR4q0Mpj?= =?us-ascii?Q?QtMUq6DmSaACIJunACrHeVnz1Nkb5w014uZkAoLllK/Xw96GE/1UwQoXm+Dn?= =?us-ascii?Q?e3ngeiQEoi3b9iONv/ep6V53OvjtSc7fCJnj4TBowunAdtivcOXKf6YhwbyJ?= =?us-ascii?Q?5J4/K6VSC5ZePA7i9dTFc0Gvrq7WaOYjIN6ytOuwlHs8uemwV6Wv8NoncwYZ?= =?us-ascii?Q?/KO7lGouNxyxWiOhvVNfwB35BCH9XS6YZD6o4Dz5bTVjZr7W7u7UcEuoMLNN?= =?us-ascii?Q?X8W46Nd/5XXBVmIuZ/iK4TKm6GJLMJTtRSLESbNhYIMP1U7IqtMhQLo23EYM?= =?us-ascii?Q?0hIkn+QUmZA3x7M8JMcjecSftSNPrfKrHjg7n+5SqOo6MlNd1BqGdNU6y9aQ?= =?us-ascii?Q?9H1C9zVpTMoCHYvE6gDtAi56uuqddv+LkTsNKbW9GImE2e27HDoNqZRg+Zuc?= =?us-ascii?Q?EVUb1npPEOphX95COmyjvxzz7J7UMEimjdMYw2K6EtYjaE7zAVzgeXGxzmu2?= =?us-ascii?Q?WwBUnOA9TtIKO97XpmxC53pG9wd+dU7Hamzf6eNSnohZS7lQDqYiZn+khNNf?= =?us-ascii?Q?Dt8i87sODLgT2V5lk7rBqoaEy+A2leS9vgT0erYJzSfGv/OT1xBVdTVgG5Wr?= =?us-ascii?Q?YZWPHiSuE0wLxGM5MLfuRLgKGoW8zC626GQ++zpAJ/VFvlVS37WrPjWGKKJF?= =?us-ascii?Q?8kDyennE5TbYgsemv6Te4X+qpOGzEhbbmDCebyJlTnKGda2jQs1l4T6yQWSW?= =?us-ascii?Q?RLjnkoAIPfmFrMpNSwcXFwKA32IOB9kN1WKwk2IdGnwPWImm36ShjuXhdjei?= =?us-ascii?Q?YGSpOtUKv5tNoz7AGPBeZsOH0vKeckY0XjhFoAf4SiuwMklQziDHNXvISRYc?= =?us-ascii?Q?XC7dlfgkjWCtkA4Qdp38P8z4KUfKk1GEo/AM5HmpaZQ64+4HfyNO3msfEjXt?= =?us-ascii?Q?OBToVCDBn5mf1hnKJJ7MlvXpD1/fBxg3O1+1//6yVb1wOWvxPwRsgGoefHoK?= =?us-ascii?Q?hWZ3d+MVls9E/jpAhPEGlW7VCtHdgnmhfGr9Al6QwgCs9OzP2yxPSfSP2c0V?= =?us-ascii?Q?1v5P6mFSb4Rtp0rvvRbSaux7Ar0Y3TvUWwj9kKQ9nq+VSDA45U/CHknhxlvT?= =?us-ascii?Q?HjRljT+BdpkOtWaTR5oyB2mMSdCR25AuhvSnqKAH0yT34Ru3m4kfpmNUtzik?= =?us-ascii?Q?35jwSAai0wFhSZ21qUqz8sNMtMlx8SQhJlbKDnz/Xi4ZFKtkdm2EIXVyKA6G?= =?us-ascii?Q?29y8rJE68tRmR2T+yVNzrn3G1hl7MkyCNOEV522uZBz9NbG5Dnb9YSQBfb1f?= =?us-ascii?Q?QrwAJRDZ4rBRsK/HSzzixjuHBuKv/F42+8jfF0F9WiZmIPVmzYHXev73ZSgg?= =?us-ascii?Q?UQ9DHqjD9aeczbAIG5axovuO8q97lcoefmUv42rHGvww5qng8rdkVK0n8oHC?= =?us-ascii?Q?OddNCrKuTEtoS1CG8Ec=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: 16 Oct 2025 10:42:46.3198 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 87eb3ff2-4678-434f-ca86-08de0ca0bead 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-SJ1PEPF00001CE1.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM8PR19MB5288 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMDE2MDA4MCBTYWx0ZWRfX1A3QWerAgDon 9+E7jRzoHLSfrwE5wyI99UzS/HehvKJcjtE2zou3jB+EFlnqn7T0pZhhV1Abb/loBOiAntcCun1 QZYn1d38Hnp3pldmUlYSK03sHN5BPPhDKwcuwqdg6+DwcNutV43R4/mbvFtAIpZVe+a6a0w331S jRt84pGnFdFhCMovq5Eydy/YKpznNIISjryCf06xniXn1LrAKxSU5Xw+sDLXDB+1s/pdWu2Zaqr pq3TI6ZhG4nrM9YbBWrxq5cpT+dEMsU/2WCp5WQfHGfZabx3+qZyATZUmAv3DQTa/Py4F0z6ktU WdK5tWT1bPPs/n0GiopMcz4zkaz7FJQppWGbVlAVotrvPOCokuCl9Y23vwzlLDofIbGQryKbCfs K3GrcZ3e9+THxbmPzfxH2Y0DZcf/4g== X-Proofpoint-GUID: kvrkGeJP75yV-1WBMoeN3jKhEjiWssju X-Authority-Analysis: v=2.4 cv=PPICOPqC c=1 sm=1 tr=0 ts=68f0cc2d cx=c_pps a=xVCXbABICjn79FXy6fcvAA==: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=x8F6GPULHbFzkjThbqYA:9 X-Proofpoint-ORIG-GUID: kvrkGeJP75yV-1WBMoeN3jKhEjiWssju X-Proofpoint-Spam-Reason: safe Content-Type: text/plain; charset="utf-8" Create sysfs 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 sysfs files. Sysfs is used here to restrict access to the factory calibration. It is only intended to be used during manufacture. It is not something that a normal user should ever touch. Calibration affects the matching of the amp hardware to the external speakers. If not done correctly it can cause the speakers to be under-protected. 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 sysfs 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 sysfs might want to know if there was an error. Signed-off-by: Richard Fitzgerald --- sound/hda/codecs/side-codecs/Kconfig | 15 +++ sound/hda/codecs/side-codecs/cs35l56_hda.c | 139 ++++++++++++++++++++- 2 files changed, 149 insertions(+), 5 deletions(-) diff --git a/sound/hda/codecs/side-codecs/Kconfig b/sound/hda/codecs/side-c= odecs/Kconfig index cbf1847896bc..0218aa41bba2 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_SYSFS + bool "CS35L56 create sysfs for factory calibration" + default N + select SND_SOC_CS35L56_CAL_SYSFS_COMMON + help + Create sysfs entries used during factory-line manufacture + for factory calibration. + This is not needed for normal use. + + 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..4a1bd934887a 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,126 @@ static void cs35l56_hda_dsp_work(struct work_struct *= work) cs35l56_hda_fw_load(cs35l56); } =20 +static ssize_t calibrate_store(struct device *dev, struct device_attribute= *attr, + const char *buf, size_t count) +{ + struct cs35l56_hda *cs35l56 =3D dev_get_drvdata(dev); + ssize_t ret; + + ret =3D pm_runtime_resume_and_get(cs35l56->base.dev); + if (ret) + return ret; + + ret =3D cs35l56_calibrate_sysfs_store(&cs35l56->base, buf, count); + pm_runtime_autosuspend(cs35l56->base.dev); + + return ret; +} + +static ssize_t cal_temperature_store(struct device *dev, struct device_att= ribute *attr, + const char *buf, size_t count) +{ + struct cs35l56_hda *cs35l56 =3D dev_get_drvdata(dev); + ssize_t ret; + + ret =3D pm_runtime_resume_and_get(cs35l56->base.dev); + if (ret) + return ret; + + ret =3D cs35l56_cal_ambient_sysfs_store(&cs35l56->base, buf, count); + pm_runtime_autosuspend(cs35l56->base.dev); + + return ret; +} + +static ssize_t cal_data_read(struct file *filp, struct kobject *kobj, + const struct bin_attribute *battr, char *buf, loff_t pos, + size_t count) +{ + struct cs35l56_hda *cs35l56 =3D dev_get_drvdata(kobj_to_dev(kobj)); + ssize_t ret; + + ret =3D pm_runtime_resume_and_get(cs35l56->base.dev); + if (ret) + return ret; + + ret =3D cs35l56_cal_data_sysfs_read(&cs35l56->base, buf, pos, count); + pm_runtime_autosuspend(cs35l56->base.dev); + + return ret; +} + +static ssize_t cal_data_write(struct file *filp, struct kobject *kobj, + const struct bin_attribute *battr, char *buf, loff_t pos, + size_t count) +{ + struct cs35l56_hda *cs35l56 =3D dev_get_drvdata(kobj_to_dev(kobj)); + ssize_t ret; + + ret =3D cs35l56_cal_data_sysfs_write(&cs35l56->base, buf, pos, count); + 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 DEVICE_ATTR_WO(calibrate); +static const DEVICE_ATTR_WO(cal_temperature); +static const BIN_ATTR_RW(cal_data, sizeof_field(struct cs35l56_base, cal_d= ata)); + +static const struct attribute *cs35l56_hda_cal_attributes[] =3D { + &dev_attr_calibrate.attr, + &dev_attr_cal_temperature.attr, + NULL +}; + +static void cs35l56_hda_create_calibration_sysfs(struct cs35l56_hda *cs35l= 56) +{ + struct device *dev =3D cs35l56->base.dev; + int ret; + + if (!IS_ENABLED(CONFIG_SND_HDA_SCODEC_CS35L56_CAL_SYSFS)) + return; + + ret =3D sysfs_create_files(&dev->kobj, cs35l56_hda_cal_attributes); + if (ret) + goto err; + + ret =3D sysfs_create_bin_file(&dev->kobj, &bin_attr_cal_data); + if (ret) + goto err; + + return; +err: + dev_err_probe(dev, ret, "Failed creating calibration sysfs\n"); +} + +static void cs35l56_hda_remove_calibration_sysfs(struct cs35l56_hda *cs35l= 56) +{ + struct device *dev =3D cs35l56->base.dev; + + if (!IS_ENABLED(CONFIG_SND_HDA_SCODEC_CS35L56_CAL_SYSFS)) + return; + + sysfs_remove_files(&dev->kobj, cs35l56_hda_cal_attributes); + sysfs_remove_bin_file(&dev->kobj, &bin_attr_cal_data); +} + 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 +848,8 @@ 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 + cs35l56_hda_create_calibration_sysfs(cs35l56); + dev_dbg(cs35l56->base.dev, "Bound\n"); =20 return 0; @@ -736,6 +864,7 @@ static void cs35l56_hda_unbind(struct device *dev, stru= ct device *master, void * cancel_work_sync(&cs35l56->dsp_work); =20 cs35l56_hda_remove_controls(cs35l56); + cs35l56_hda_remove_calibration_sysfs(cs35l56); =20 #if IS_ENABLED(CONFIG_SND_DEBUG) cs_dsp_cleanup_debugfs(&cs35l56->cs_dsp); --=20 2.47.3 From nobody Sat Feb 7 17:19:48 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 9E7413002D6; Thu, 16 Oct 2025 10:43:07 +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=1760611389; cv=fail; b=swNcy8YrLhQ/WrhSETZIcvUcptPTN+qHHzs5l11T8NdfB55XKG5Xgcr6RzXxfrc/qL01jAIr/BVd4oiRh5kHWvovPB5t5i4Q9L1Qr2rS/JVBeqp+cfYey3FFNXTidz3NQF6iEhuWgw0lnT9C0+kP95zN2GPunBXb+MhcAh+HkGE= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760611389; c=relaxed/simple; bh=oLwQWGfCLXmS+vWfQ64mWrRjgyLiJXzUGfjdppst9ag=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=sxR0XVHfn6WaYE2+QnP1OjlP4HW4DBeMx27HbBHTaIHbUh27U7utcDrqcsVWtJa5OmN7N0i0/KtYldcHOSTslrkPpM2mpxtYiEX/XDCmqIsFc45LtdT3ZWjWxj/V/jgKd8SFcthr5cRrtW8z9zvDG5w716+8cPrGW+8/NzsDJsI= 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=p6CZ844q; dkim=pass (1024-bit key) header.d=cirrus4.onmicrosoft.com header.i=@cirrus4.onmicrosoft.com header.b=Z7vUtFPp; 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="p6CZ844q"; dkim=pass (1024-bit key) header.d=cirrus4.onmicrosoft.com header.i=@cirrus4.onmicrosoft.com header.b="Z7vUtFPp" 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 59FLY4Gf1728970; Thu, 16 Oct 2025 05:42:51 -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=GU5tH7J/4KN3ZlxgA1lCJ7G5tuj/QsuCYXyJGz20a8E=; b= p6CZ844qG1oRj2xaeWWm+YeZz/mS+4tkfNIXlR1Roi5g9gNPn5SOFS97BmAVw24C j/Pq0iggrNv/e/+Mko/S4mFbImPq06KvWI19QPq3KgeLG+kQZ/WAlbIccKKdHCb9 UndEUfYTVYGaZ+r1rmurJu6p45ehfkNZoY+XHPFad8+LBzWsbrr26krQncnwjQl0 xLMMKk+KU0iD1sS6cwnyxuYgaCNeiZYPaYsa/+r1JAjRPMLgYiJ8RRQlr1OSuiZ/ 5WA6awLKXziYpKzt7hGUO0MJ5kIuQttP+2SzNV2nR5gpM0PQC9j1Z8sITPJQ5Pjj rJNg3A6J4kPJ43VVO2es9g== Received: from dm5pr21cu001.outbound.protection.outlook.com (mail-centralusazon11021125.outbound.protection.outlook.com [52.101.62.125]) by mx0b-001ae601.pphosted.com (PPS) with ESMTPS id 49sdb448a5-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Thu, 16 Oct 2025 05:42:51 -0500 (CDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=FYpVtEryaLTzbopSZVwp+YT0XSZBTMaCa9mrz3xOjl1HMmCzhPHZF1F9HdHAizvFUh8Th+kXRjb24Uv9rAYEUnktRagH29HwGaGuUtQLkqM4LS8roA9XJ82T+ee+L5Ov8o//MbLp/JQqy96A+Ey8GUFweFxo0CG2AKVjsaVN58N3LnFaJtFVkY+TOojNJcjRKVjWU9VM5rxU3t76v2++vetr7wB6fmrVancEFSbCU+euZ9o4qjDdUdvI42iQmNsuxsoTTMe1j7h1ToMrked+02jOUnU4QW8cwrrlB4rRzyaBxbrpvz+MnEVgISvEMxhz3IfcTafmWuNIo6jnaW51dw== 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=GU5tH7J/4KN3ZlxgA1lCJ7G5tuj/QsuCYXyJGz20a8E=; b=sbiHMsFH4PaEFOfYljxlf1zAq0442URMAnC2VgNWJL1oda+Rx9+vBckNV+ZGDHcsx0bSMGdsHzOW3K4i2+0aNkKLK8qg9oJ1GdZ5GyV0/tzAONcvrJYebovvtc+y5nReP1ZiZVA4SLmnJ4O9ZO5U9i7frbeKeazH7sJvWKUqYo0ZALZOxaASD3rORVDVSnuuhNuGAo3kZqs7rzHWv1m0e6s86ojZjNBxUFc4bGiIAw1I9azkiIDMLxaRpUHZ/HMVOkqJstG5tp+pPqJleSd5m6M8rSxWSp0O7uPuy8gHzNGrYvnpbnb8Y00zI7Y39CO/4L5AdwdX547DchKWE4lv7g== 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=GU5tH7J/4KN3ZlxgA1lCJ7G5tuj/QsuCYXyJGz20a8E=; b=Z7vUtFPpbN0o9aPbYNUBJLADo+HIv8txXXhOLzt2TbYxS2L/KK0CPEaDSVhYgZV0EpBJ/WW6xBkJAynnZ9w426ynZIhOQgWqStJV8dXSpeYew0xXA5HHDDg4ZkTBDkJEhdaO/rZSmlV1prLvOvlUTyue8oj+zRJl6KX5peJjMg0= Received: from SJ0PR05CA0095.namprd05.prod.outlook.com (2603:10b6:a03:334::10) by SA0PR19MB4349.namprd19.prod.outlook.com (2603:10b6:806:91::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9228.12; Thu, 16 Oct 2025 10:42:47 +0000 Received: from MWH0EPF000971E6.namprd02.prod.outlook.com (2603:10b6:a03:334:cafe::5a) by SJ0PR05CA0095.outlook.office365.com (2603:10b6:a03:334::10) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9253.5 via Frontend Transport; Thu, 16 Oct 2025 10:42:47 +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 MWH0EPF000971E6.mail.protection.outlook.com (10.167.243.74) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9228.7 via Frontend Transport; Thu, 16 Oct 2025 10:42:46 +0000 Received: from ediswmail9.ad.cirrus.com (ediswmail9.ad.cirrus.com [198.61.86.93]) by edirelay1.ad.cirrus.com (Postfix) with ESMTPS id E751640655D; Thu, 16 Oct 2025 10:42:42 +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 C7200822543; Thu, 16 Oct 2025 10:42:42 +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 06/11] ASoC: cs-amp-lib-test: Add cases for factory calibration helpers Date: Thu, 16 Oct 2025 11:42:37 +0100 Message-ID: <20251016104242.157325-7-rf@opensource.cirrus.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251016104242.157325-1-rf@opensource.cirrus.com> References: <20251016104242.157325-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: MWH0EPF000971E6:EE_|SA0PR19MB4349:EE_ X-MS-Office365-Filtering-Correlation-Id: ad3b9c86-fb2c-4b7d-ecdc-08de0ca0bea2 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?Q+iYnqQwTFEl+p3B8ZI2AJi1k/U79sPUTkTPqg+jbOmAv06Yamxgm58tM1Bq?= =?us-ascii?Q?+QaX6s6rJh7oG1QWhsJi+BVmywhuhiG2PcgvZhbxrFoTJeugOvSh1QV0sc/G?= =?us-ascii?Q?fa3MqmplGQWLv3p0M2iPjJSZFDrfS+lTQgx3UmlKphUFrNTAmJRfvKEDGjjs?= =?us-ascii?Q?OMCn1RnERaWbbt9PW5Ifs0cOBqvPNL1vNVviqWhfYGqXr9QmVzkVr6ql55gG?= =?us-ascii?Q?9tSr0cs70WQOAmyakrhTWrjtggTr0ljKcXW6uxR4tvOk9Lxf9/U7anXXcuHh?= =?us-ascii?Q?KUPmYS7hvJSZYAjH4uDhk8vWWrjD5xoG6L8PGJN4vEak0Q/qjBUqeNGTnyP3?= =?us-ascii?Q?jCWaSmqbM8xqe92Yw5c5FkG8BRzv+UrFhpCZ3ozOI7jZSIT6GEd6q8W+CVFD?= =?us-ascii?Q?7iqnrOdSqLDn5A4h57hMnwGU7FURG6vAIvULMwLEzf+PWCkZ9nBtXNIh0J1I?= =?us-ascii?Q?GvECls9XExJC0ks6GGoWr8tz+YbboYPXmd/kP6X7107kpul1iTjVgUl72PT4?= =?us-ascii?Q?vC2Mb0iSI2JyTTuvgn8GXPvimQWVnvnJjmN0hLOd/8ZJ8IS/9NmHTPvR5M/Y?= =?us-ascii?Q?A3FF9bRoqQaeMeT7pcGWhwvHfD32Z4fsUzXxVpLnPu2Xb4qZJL33Zw1G0NTP?= =?us-ascii?Q?sg2TuYxWCayTi+ncNhKjxWujYBMgKcTUxmm6jWBsBW+s1sLHJvEYwn2CDysO?= =?us-ascii?Q?4FsUzYhv8HqOVpx8W6DBSXAVXb95pFqqNFIH93yhjJqL02v52EXmthbuD3j/?= =?us-ascii?Q?JgIn0i6lFJ4lTmeSFD3WY2RSq3/lxxicOqELIy3AN2ayi56DShvnZtOmOooV?= =?us-ascii?Q?bpAbKM3eHSoceQ1W0oDIGThLxaf0EG+6TEik3a/L7McRSUzGmgwisPJsqDuj?= =?us-ascii?Q?X7Vqiu6JsElVAKmnEfs+cJhu94U7ry+rnGr9LtkxaN5UsptCOF8dXe7HoFPg?= =?us-ascii?Q?gHb1pGnHvX4SRrSUOJnCsVMmC3vktpoY1Z4ZCkzJepPSBUEOxLeEsyUEW6Wv?= =?us-ascii?Q?YXjmhKyx8xYFnCYV5lK+MCbGCEF7HgdeSMb0hXpu0f30jkYzICf7qWgCeA8z?= =?us-ascii?Q?T23A/5pjP8R6NRhZ2tMvg2TowtBrgLjkFAkxVdONS6WuLpewl1bw/l8pYVJw?= =?us-ascii?Q?hIfQVmuUU5Gg9US5s7/bOqcBkztHF0h+Vf9WfMvE7DVwWLn1Cb2eiuJmlADO?= =?us-ascii?Q?1ufiUkY2mG4APOaw1JAb1gHPpKTZg00k9ToqwF6Ye2AMmDUhtLnCKQnW2XQV?= =?us-ascii?Q?mJ0b75TD3QoVbYL2PBOQQnIFpysKccQkenuELLY8Ksc+ryh4CQ+nMo/23DBz?= =?us-ascii?Q?L+O0bORtNmD/NWDBPm3xePjNxvxe9M7miPZc0DjPSSo6OPpf/ClDO43Uk9q9?= =?us-ascii?Q?pZ7IjIebLU3qCEYfDmxno5MBnDF9yKt2rIl+NxkalVCUKeWi9H5HhF1R5U93?= =?us-ascii?Q?379W8ZlMnVSynT3AXyT0LPJ+6+aWPDoFzPMUIcEd0YjxE92J1mBSUKzIe6Wb?= =?us-ascii?Q?jRwyyJx9x2B8M6tJWTSKpNqru3nwdVGERs02YZBSRz8i7FKX3cflyO9nwC7T?= =?us-ascii?Q?yfjK01fGDNNymfV8DxQ=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: 16 Oct 2025 10:42:46.2669 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: ad3b9c86-fb2c-4b7d-ecdc-08de0ca0bea2 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-MWH0EPF000971E6.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SA0PR19MB4349 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMDE2MDA4MCBTYWx0ZWRfXwwRpj4Hzhwm0 ighzlmxRUJT4Rx7p9ZwhI++MrHr6wlEa6+CzTdo3/n1HzXswcGv0rfPrDZLsmfJdM3ZuPi5I/RT w9nNA9MrzK5VJ6tS/tZkjeWYUFegI3XRDvLhBsJLc+XNasihJbNI7sCTjOQ3AnVe2LDmHqd0Nh0 wlOC2rRCURoUBhqNuVc4MxC0ri1m+sSG3u2n7kzB0OIRoxURbw1HfqjFrUK0pm5Jb66ci+0AHmB c82m/9g2+rrDNY0vqCiH+xerm+MzDuo+IEI2faWIMSVIpYw1EzB07kry3BbzjteOb6MXL1vgbqP r3756WF7v1j2xlRNAMvm+aFUeB6T7KEUZIJewKEedy1Klj9ZM6QNLd8uhOD/HfJAikzsMjVi4tE aXsa0PQqRu79hTIwsIpJtwKMGZxH9A== X-Proofpoint-GUID: 9W192a3gwiD0HWVCKMGfwaq7K6pj2nok X-Authority-Analysis: v=2.4 cv=PPICOPqC c=1 sm=1 tr=0 ts=68f0cc2b cx=c_pps a=63eZqvGvmDVpXZrU3nJVyw==: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=7xSZuedwfSVow7RlVg8A:9 X-Proofpoint-ORIG-GUID: 9W192a3gwiD0HWVCKMGfwaq7K6pj2nok 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 --- 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 e4df0736039a..485daadd13a1 100644 --- a/include/sound/cs-amp-lib.h +++ b/include/sound/cs-amp-lib.h @@ -71,8 +71,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 3406887cdfa2..b19aaacd7f2b 100644 --- a/sound/soc/codecs/cs-amp-lib-test.c +++ b/sound/soc/codecs/cs-amp-lib-test.c @@ -702,6 +702,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; @@ -974,8 +1045,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 b2509c5c0690..d510e0e065ca 100644 --- a/sound/soc/codecs/cs-amp-lib.c +++ b/sound/soc/codecs/cs-amp-lib.c @@ -515,6 +515,7 @@ EXPORT_SYMBOL_NS_GPL(cs_amp_get_vendor_spkid, "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 Sat Feb 7 17:19:48 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 3295F2D0C7D; Thu, 16 Oct 2025 10:42:54 +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=1760611377; cv=fail; b=FbMDhaS2zkHkW7QFFQj4KOhsVFM0O1ChK6UQinE2wiLvM/mOHmN5aOPhYGY9m/5xuCQHr/TS1JgFnjv6QbTvToUM6INyv0yR352Dcr48ID0XL60QcpPU4+dMdPYnaGgPGtcScDlXyX5uYv773NBCglazFHq9vwm30JxDfeoARaE= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760611377; c=relaxed/simple; bh=Cgk9IY3u/WIJhEImYCl7n0SAzHAo1ogDATxJ4kvx4aA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=J/KrxbWEoTReBxKvX1q6AX5734M4kW5VZQHlAq3qlGi/mK4NV1tjePKIb1gFq1qKmoRGNqn4y/fPzta2Lv6HpA6RU5u8AUofDa35FEatfwvAZ6x4ZPCBpjT2nV8HQxovJbHfOdmUpSdzuPtjpGFMt398oG/I/+wmX57LD+dU5Xk= 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=WbLtwi/D; dkim=pass (1024-bit key) header.d=cirrus4.onmicrosoft.com header.i=@cirrus4.onmicrosoft.com header.b=D2xta79h; 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="WbLtwi/D"; dkim=pass (1024-bit key) header.d=cirrus4.onmicrosoft.com header.i=@cirrus4.onmicrosoft.com header.b="D2xta79h" 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 59G8fDdC2477160; Thu, 16 Oct 2025 05:42:51 -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=07aQvwIWOtN4aDdY5MQWVzSxBzrdKpz/FkcV+YgUI/8=; b= WbLtwi/DpqE83FFurVPpH7MoNTQmIgidLpVtcOkVLz6WPvldSIQ2Y2vZ5Aew/A4R uxP7Z7B7vVkKAFHcol6uDP7feLXrQwazCJpJ+lI21No09k9kL/7AnI6bqZwL1YoQ RhsT8nrxL0PNQkxvc5T7Vt7Lo6mlBcsVTjXANkYNGQwwq6ZmC+5GorZy87+1CvHZ XSfG6J9j+wRoN6mO+849P5hiZLGCtC1i0TAs79nkRGJndl81xKZYfSP/uCjmZ/W4 8rM/DhYHYpao/lQ7dVFtI/dfYCT5n3Z8XFqx3WJHM4Q1dJPFCPNCAQQTcubacU4j zubNjaNG2UCJWUzQNCtB/w== Received: from byapr05cu005.outbound.protection.outlook.com (mail-westusazon11020099.outbound.protection.outlook.com [52.101.85.99]) by mx0a-001ae601.pphosted.com (PPS) with ESMTPS id 49t9mhhpx1-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Thu, 16 Oct 2025 05:42:51 -0500 (CDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=ZL543IwP4ayQnNiCcXAq5zkhZOXdzLmZjn0hJIyXt3Dp4SrEZ5DrnF+vQAeFiMPc3cT6cfE9bITlgnKNYc9MKNStGARTI4JxOLVH0k4alGQxcd6gxZ24ywxXpcqa2LxJurwMatuop5Nwr1Y6FxhVpBPE9wD5vHLYA6RXM8J9QDFy1FJJKYXxJI9Kpy3xm1acHPayniVbs/MemoTckOiJNXB+OFIg6P3brHOGAY5lMHMprmDfNxqVdL3NpjvKlM9AJmHPmQ+n+NSDDtx6SNlzBt+DYIEJKGxDfT1axglqAmsvrtORsY1P5wnA+qqWcjI5ei8Hm5WUpf226MH63LODGw== 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=07aQvwIWOtN4aDdY5MQWVzSxBzrdKpz/FkcV+YgUI/8=; b=M0aholpOMYOI+7wsiRn4c5FP8nmNwgjdsDA8Qu1JGOwt6pPbuwLbyI+bKcKjKaSEbNIWmqvwRxDFhzFqea1zqtDUcqkLX6hxjSUEtwEc+HjbqWu+hfo9kr6m6fOaWusmF7elMV1HT3bLSJhRHz0sEbpxGC98K9aBiD5v3E/ZX5hTrs9qYtBQgrEIfyDM93pYIc5tYPjEka98DoPj+26DWc8Nu6vOqxAxnV5EVhgDgveejGqced9sdybY3g0+on+aKPSYqwBWTCVm7ZRb3p/actLgMOFrWtb7+Qnfa5Q4LtHt9K7OMzSfHQBsRU6lzFarmvJ9Mm66CvhaxHzm0uKcTQ== 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=07aQvwIWOtN4aDdY5MQWVzSxBzrdKpz/FkcV+YgUI/8=; b=D2xta79hm7egNlfpk+Xu+p6KKZ2/xRysubg7XWQKLrAEXPX7MvnHaqTH1E9iWKZoRGHUKrmABXwinoz1C/0eS8D/mxgppLsn7V/wf5qw1u1HIUx1AQIc/q2jL358coq1hMwTgkV+w/ZCm743yYirKmHtlc2q0Nr+v+HS58wUCvI= Received: from MN2PR08CA0028.namprd08.prod.outlook.com (2603:10b6:208:239::33) by SA1PR19MB4992.namprd19.prod.outlook.com (2603:10b6:806:1ab::8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9228.12; Thu, 16 Oct 2025 10:42:47 +0000 Received: from MN1PEPF0000F0E3.namprd04.prod.outlook.com (2603:10b6:208:239:cafe::a9) by MN2PR08CA0028.outlook.office365.com (2603:10b6:208:239::33) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9228.13 via Frontend Transport; Thu, 16 Oct 2025 10:42:46 +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 MN1PEPF0000F0E3.mail.protection.outlook.com (10.167.242.41) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9228.7 via Frontend Transport; Thu, 16 Oct 2025 10:42:45 +0000 Received: from ediswmail9.ad.cirrus.com (ediswmail9.ad.cirrus.com [198.61.86.93]) by edirelay1.ad.cirrus.com (Postfix) with ESMTPS id F2D92406561; Thu, 16 Oct 2025 10:42:42 +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 D41AB820249; Thu, 16 Oct 2025 10:42:42 +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 07/11] ASoC: cs-amp-lib: Return attributes from cs_amp_get_efi_variable() Date: Thu, 16 Oct 2025 11:42:38 +0100 Message-ID: <20251016104242.157325-8-rf@opensource.cirrus.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251016104242.157325-1-rf@opensource.cirrus.com> References: <20251016104242.157325-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: MN1PEPF0000F0E3:EE_|SA1PR19MB4992:EE_ X-MS-Office365-Filtering-Correlation-Id: f038846d-1cef-40bc-bab1-08de0ca0be0b 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?89KYtlQ7+drrs7voaVRA/1NiSKsI3lIs2guHyXlcTvfXfwRAZXa51Uo1XiRY?= =?us-ascii?Q?POkdxYiBqxM362g9SlMClEUvX5rRFToHcVEIqTFGVcf61Cv2erpyh59Z7skp?= =?us-ascii?Q?QH8K9LT0rU7R6zjNYgibGedv7ouHOU4lk+DfPbXvqOXewIQCdFIXdsWdRc0S?= =?us-ascii?Q?m320kBbFuR2gtXkf+FY77umWZP/ERGMGWvRLbwNBb1YVyuNUWk/agC61M8pU?= =?us-ascii?Q?lzcBZ2KXY/0mdR4IOwez7bczcRWkz0A40sTo133YX6A7ceLEEd9fN8TLMrMC?= =?us-ascii?Q?3HIoN0aYO7CIZPGl+OpDFEOXHqDUjJerteGjXNbZuDe3mPESb52y6KO7WFJT?= =?us-ascii?Q?GqPQfSP2W2nMaPZ/1Rgkt2lWvG/SKmANssUZPKfS2M59UgJ6Xr9y+YIrtKqQ?= =?us-ascii?Q?kwWHJMEuiUbdqUDBTGnf/od4L3Uz5SUOa9LijYbvWAlJINhveP7bj9KT9IE6?= =?us-ascii?Q?CdGKuze3dPbUikSPvJa7Q51+X1BRo7jO864ihAgy23NJW6OFiI8Ui8alUQqk?= =?us-ascii?Q?PPzGWlk2aw/W9Chark07EXiaZpiHXN02V/CqFYvR+m5NScCxlgrO06U4FhTS?= =?us-ascii?Q?oN2jWVVQ9BnBg70FvVYnXaL9qS5XyydzNtyBPlqCOc2AqM5lQIvlEGr3HPnd?= =?us-ascii?Q?rrgC2Yo6cQUXT7+jZpylzWYJLa+B1ll7ZzGW57IapLdwKk993c0qTxRMROBw?= =?us-ascii?Q?QZR6cAJ8/pHYwIN09ci/5NDnBcgEbA/xFZauPXkOUOtUHdQiVs2/TvaxXcEg?= =?us-ascii?Q?JshmyCNpnn1oIKl8Ry/qhpxywVgT7AMSQH0w0PbQqWcgphndGd6KV2mcZQ3I?= =?us-ascii?Q?0hDbXU5bYVXgDXv4tXe0kp/0g/mQa3ZyFG4tADlHTPMigQTfo2/cfsAnQEEN?= =?us-ascii?Q?psMyd/UuL/X7jPLuYDwLmMBgUTbVsGDD/pyXBPaWrf94O7SIzRI1AhopYbKO?= =?us-ascii?Q?X61zaNg8D3UrPpkU8/Qy37CyEv2RKzc8ufWrfud+3f3RlAvWROjN9IVfpKDb?= =?us-ascii?Q?oZwhcmaZY5713OI0dhcTuUl3J8NkBletZ1wR6Ti6VRGODjEsasHzTzdb8fvh?= =?us-ascii?Q?zqAXv2Q9Hvfk0I0gyCaj0NAPE76Uqhk+vg6I/JSvasjfYfsbGeZzXnyVJdjz?= =?us-ascii?Q?mscLayRlA36yR8RMW/r3IT5j1UY71XjvaCp/phMipSBDMc2imEw+XtHisZ6E?= =?us-ascii?Q?OYTu2vhgfyfdLatdYDFDTRZ8/1NdG9xua7bptqQ2wG3ZUqR2LxZvQpD0p6Vj?= =?us-ascii?Q?4lM4VI3JnASV3upIgIxW3Ou1Zp8Qsaf7zyN6LY+ashn26bFExhp+IIT5grsX?= =?us-ascii?Q?ehPk5kDxnOEi0JpoUTh7pRDvmszC/lDqAQOrzYcKNo/IiWv+2gayHIoxz+/X?= =?us-ascii?Q?8ButH/lsvNQptgUp3t+eOqKwlwdTKttlrUqgDBivKaLV0Vg6Ac2B8ToBS3aq?= =?us-ascii?Q?spjjT9rtdOsb+Uf8Mbn/ZggeOq12V85vd/uz7rYVIAB06zwQYGgjeJxthOwm?= =?us-ascii?Q?s/6fLjIq2YmGjOYHavO0XB1mjuS3VIi6JwN19NAdezdBrMe4d7bCEV9niYzn?= =?us-ascii?Q?keWulqCbqm4YqgGi/8I=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)(376014)(61400799027)(82310400026);DIR:OUT;SFP:1102; X-OriginatorOrg: opensource.cirrus.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 16 Oct 2025 10:42:45.3865 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: f038846d-1cef-40bc-bab1-08de0ca0be0b 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-MN1PEPF0000F0E3.namprd04.prod.outlook.com X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SA1PR19MB4992 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMDE2MDA4MCBTYWx0ZWRfX1Tkzl2l2ucN6 l29Vl/vy/fbEH4+sihTeXKz/4fY+muo5Hd0GSykcTjYpcZmCN5/wMmw7vIaaTPNk1nTOiKF2lKa Y5aJdCa+4TTVNEOH+UoGIK4ZwGhuTDmFlx21evBpsU9mUCvohO0/IfiyU4yMMvdsFwqXMmBjt+N UGzRdIUW4BLqoeiTEgTj3qNKnp2ZcQZFfF911vC0hrUxnam+pC+eqHZCAFE7uzUbw+dUZlFy8Ap CpaAnrBT53M/OAvQQSS0hYzIAQmobEGi7be3C+F1kLIwztVP17PyL4D1aysnlI2YcsmKqbsWbcQ N9NbuEb/l+yLbPXqRMI7cDbz4TyuDxE5rKkyzS8TkeJT5pGRelUWjE2TzX5OpnDKj4c+zWKJG2r ftMxUUtUSu4AUzBSJJ/HvRuN/ZYx/w== X-Proofpoint-ORIG-GUID: rv6O3ek7NeHEgtjYFHZk1ll-hfWJxXl1 X-Authority-Analysis: v=2.4 cv=OJIqHCaB c=1 sm=1 tr=0 ts=68f0cc2b cx=c_pps a=GGH+j3rhJf5zTl2H81NwCw==: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=BfivipjO2gqBdDjawAAA:9 X-Proofpoint-GUID: rv6O3ek7NeHEgtjYFHZk1ll-hfWJxXl1 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 --- 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 485daadd13a1..09c54b1bbe6c 100644 --- a/include/sound/cs-amp-lib.h +++ b/include/sound/cs-amp-lib.h @@ -65,6 +65,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 b19aaacd7f2b..d3419f48297e 100644 --- a/sound/soc/codecs/cs-amp-lib-test.c +++ b/sound/soc/codecs/cs-amp-lib-test.c @@ -90,6 +90,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) { @@ -122,6 +123,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) { @@ -165,6 +167,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) { @@ -192,6 +195,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) { @@ -218,11 +222,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) { @@ -249,6 +260,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 @@ -787,6 +804,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) { @@ -805,6 +823,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) { @@ -823,6 +842,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) { @@ -874,6 +894,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) { @@ -894,6 +915,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) { @@ -912,6 +934,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 d510e0e065ca..2630ea6a8f3a 100644 --- a/sound/soc/codecs/cs-amp-lib.c +++ b/sound/soc/codecs/cs-amp-lib.c @@ -244,15 +244,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; } @@ -287,7 +292,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; } @@ -307,7 +312,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; @@ -451,7 +456,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 Sat Feb 7 17:19:48 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 9FCAC31A061; Thu, 16 Oct 2025 10:42:58 +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=1760611381; cv=fail; b=X7rBtl6F8Vm46ivVogO+vt9Fdfqd8f41eB//NPJnlcrz9ZfWANd4OFiDXQFljrkS/77PTJ17w1j8HYQQZVloNCxME6lUVZ4jJn9drJ+BNuqcYyVdluFjDbntgc2WrC4D0qQvE96oPwME8zckT8Hju2OrImlxk0Peu5Ry/HXh8M4= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760611381; c=relaxed/simple; bh=hoLtWMQdm/5RP3W/qFhF5fpqd9K4KxyrQ6MunaitaBA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=uGXmyJ9eQ3cwHdkfmDbmX8rUHTcOPVdP/ibuXMutic6sdikKiwlZHtUyXiG13P8kf+/tg0JQP5kabYkOdc5YGcSHvRhpw28i+xG4hI2lYEnTYVD+fyYC361jnBAPzE1PBJTMA/rbqEqYqE/CEt6XfjQudNe7xL21kemRTfvcnlo= 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=aQHy1J1H; dkim=pass (1024-bit key) header.d=cirrus4.onmicrosoft.com header.i=@cirrus4.onmicrosoft.com header.b=o1w2w3td; 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="aQHy1J1H"; dkim=pass (1024-bit key) header.d=cirrus4.onmicrosoft.com header.i=@cirrus4.onmicrosoft.com header.b="o1w2w3td" 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 59G8fDdE2477160; Thu, 16 Oct 2025 05:42:53 -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=yLw1YDXsv4VlmjiWJqqG2pI5bwANWIKfg3OJ8PPMYDg=; b= aQHy1J1Hk0zh/ja9pctyrJ0YsYAEjZytsxXJR7NjVqsdNwsnFmD873PEQoHo4qOC QEtwnR29+2n59SxQ5Slbkhz/Ngv0zVpCRm4aYQhOQUF/Ipv0zBPDxfq3kiTjjTi7 ivD81KPtqs4vtlVjWIpCUPgyCJQZuc72L9fBiK5NbPyxZGWtgBlijBuct6l4uPkh 1lnBGs1VFROsX/GOk6KIUA+39rg/eBkh2tj2wREU8NDsxGYAZ0utjXefV+noPB92 MlGrHQ3ZPDMF4n2gUkKsRzHMOvctzMyOp/CBcszfYidEOpcojMB6L7vCUdOU13B3 gcAo9TOy0Ed0+/ACYDr3Pw== Received: from sn4pr0501cu005.outbound.protection.outlook.com (mail-southcentralusazon11021140.outbound.protection.outlook.com [40.93.194.140]) by mx0a-001ae601.pphosted.com (PPS) with ESMTPS id 49t9mhhpx5-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Thu, 16 Oct 2025 05:42:53 -0500 (CDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=ZxAKi+0uA+j6fKcUpShfZgJXnIpbV6NqIKV+MkvgrKKD75Irj5eCa9/lkuUI1HMaJUKp6qJrOmRCzLfPR1bRll77rmOQeF60lmiaVbKbFkiYfxJ03Z3K2BxkwePV5rEPXt6OTmkFbVWkGK6F+fgtoDn+Ko1d9+UyTdFOl5adfnJgyjoWTI4ftt45mNk8JIAQCPPIYa7QaffmSCQLal1DcGArJA2RCv6Aqc+Tqhqw6BiCfqx3ziPZ/VSHKoiiYh2N6OrxaR/FaZCD0wvWnKJKKEslg5SeYY/1Edtw9h7lFY8an/koPKiW6PU8ZY4udFU2Ph4MKh377FVMxW+bvs7e6Q== 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=yLw1YDXsv4VlmjiWJqqG2pI5bwANWIKfg3OJ8PPMYDg=; b=HwDY6+Ouxp3GsK02e89EsST6YvKTsaRC96+KdF/oHsADaz/ANTZFThLc29whCGt27DcIKLOEt1cneVPojQSV7+sKuMPTiVwWHnodcuvr/zuq+T/WvVO/oTVWQOwbbxaNwCKAwYAlg/Hc6u9eiUdPAyiFeXAOQ+C72dcFl/WfsL/Tu036x3yVCMcXFb8lAYMsH7K1RfMAAadbbFC31kY+2MeSGGx7+O/4PEDr/6rtdcdH310zwKy/M/Y8RxRdklX96pzjZjKT2UtmAz507YRWNwKTtkRTEQE+Qs4j9GxSNMF1cM9h01uqw0P2+3Qi3OI2jUgKZjU6w1l9EuzVhn7Leg== 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=yLw1YDXsv4VlmjiWJqqG2pI5bwANWIKfg3OJ8PPMYDg=; b=o1w2w3tdkfVQeN+5EFBDGwbxpnHUzXAUh+GqvjRFx1tYMHz8L6W8cqq4RZrD2FkKhWCjrvlPZ3WR0nAQF9Z/G6n/UEzcH0UNJHxXg8yODNsBWSrunztZyk5X+BrZ6jYztPnm1NeOwglW0Ao0p8ZUodT08D+0UZpJeGkVm/gU7N4= Received: from BYAPR04CA0025.namprd04.prod.outlook.com (2603:10b6:a03:40::38) by IA1PR19MB7943.namprd19.prod.outlook.com (2603:10b6:208:44e::8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9228.12; Thu, 16 Oct 2025 10:42:47 +0000 Received: from MWH0EPF000971E2.namprd02.prod.outlook.com (2603:10b6:a03:40:cafe::b) by BYAPR04CA0025.outlook.office365.com (2603:10b6:a03:40::38) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9228.11 via Frontend Transport; Thu, 16 Oct 2025 10:42:47 +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 MWH0EPF000971E2.mail.protection.outlook.com (10.167.243.69) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9228.7 via Frontend Transport; Thu, 16 Oct 2025 10:42:46 +0000 Received: from ediswmail9.ad.cirrus.com (ediswmail9.ad.cirrus.com [198.61.86.93]) by edirelay1.ad.cirrus.com (Postfix) with ESMTPS id 029DF406565; Thu, 16 Oct 2025 10:42:43 +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 E3C4C822540; Thu, 16 Oct 2025 10:42:42 +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 08/11] ASoC: cs-amp-lib: Add function to write calibration to EFI Date: Thu, 16 Oct 2025 11:42:39 +0100 Message-ID: <20251016104242.157325-9-rf@opensource.cirrus.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251016104242.157325-1-rf@opensource.cirrus.com> References: <20251016104242.157325-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: MWH0EPF000971E2:EE_|IA1PR19MB7943:EE_ X-MS-Office365-Filtering-Correlation-Id: fa202a7b-f570-4bc1-f930-08de0ca0beaa X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|61400799027|82310400026|376014|36860700013; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?4ldPyEbkJgddKkaLm9gmTegZcyGe5hl7t+lK07aafEVgoyHyww4lCoSY7evA?= =?us-ascii?Q?+ZDWcBRumUatBBD7r2kMOaRhTPejtr0vT4G6s8tKdqUqnPiqMathpR7lbm6A?= =?us-ascii?Q?G0BtYRw5D0XXtzCEs2BekPAxdR5V39GrZGkSP4hAO7mEVsfPDKmcbfV3RhKG?= =?us-ascii?Q?14BDqTTX5iEiTpb2g+E6rDQb5NSUyEdSi5tmrSx5nNFSFkIjfezqy/ugO5LV?= =?us-ascii?Q?x/wjYf3zqlAbvfxmbOn94WrNorDlwqWyiwP2BescC13XQTGLLAmmWNbT2k3+?= =?us-ascii?Q?FnPv3k4rZoAynm8nws27E43ioQ6M52RjseVC7AfmC+zqYie8U7mmLSeOFyO+?= =?us-ascii?Q?i7qsE3RivumIepsJ7LTu5ttRkzNuBycoJ822fmScWi09/ThIj+icv+kZpZSS?= =?us-ascii?Q?Kif7G1heccu8tX17omlw6FXwFUKU5XIDIO9qDkg006eyE1M2AVAhbEH+OO1F?= =?us-ascii?Q?f2EJZaHP7uH5e7lDImZi3H4wEl3WyUl+xe6EvBrd7HoaxvnpEH/OCwCelC/Q?= =?us-ascii?Q?NClP7BV1sR57KsBM+hOwjmOYdE3OpqNGckLVQuiqfUeoocaceuLZQFiBG6o1?= =?us-ascii?Q?08UUpawyrTYyODs1XBgegyfBBk2SMd85gltJQsbWM+8Qi8yy8MxRdL0XQ/8g?= =?us-ascii?Q?F7MULudCzgaUVPsa+isalP/dgUS+Wsu+VAkY3RrBwxn34FgzaHYQiHKtJi9s?= =?us-ascii?Q?j/3p0rqlp0CZf1o+iouw2GnsPUAbOlq7lWGHio/vtBDD7o3DOoOhDbGBIEMS?= =?us-ascii?Q?Qi2/59JwcV9hCNp9Wjr/dWdh4Ahk1rijdxz1yndRJhKcziy115w7/EOhRROt?= =?us-ascii?Q?gjcbeLx0InLwyg8TUl4Uc8mN1LaRQYf6ZPKY0BkBICuV6RuDi5DbWWRQTMkT?= =?us-ascii?Q?FyFXmtPbasyQLB5Gi7TfFqR3mpk8sUKuhD7H7re1hDixaGDme4wmGaKaTY9R?= =?us-ascii?Q?x5Bp8oveTBE953ZAKsKR7glIi/g1AgbHKUps7Cm2XyoQ6fQ1VXRZotETDtAG?= =?us-ascii?Q?XXYaDWb2IUTQL31L9Ieypnr+APEhgosYjruuYa9v0LwSm5sSsxvzwNpxehq7?= =?us-ascii?Q?9DeB48w/RPSFFHF5rFYJm2tQQtbGC97mL8BZ399uZZqrrieWiM452hpqefc0?= =?us-ascii?Q?I03yaohbYwp3lYnVmASWI1uFCa5yt5WzobYu5pIcCleILwHdXM+SCyMcDMeZ?= =?us-ascii?Q?q41905ZabU2SON/so0jEQ7tL+6fDSWCgsY69aUCPRCgyxl7Z2UHTesFB14qz?= =?us-ascii?Q?iciKIeLjia0L44MRZDEH49Q5HPv71gbshTsIQjukxnPLvZcpBAsPbgwKgIPn?= =?us-ascii?Q?LY3ue8kQeAyNnkPRmnw4dNCSdsWUUTMxxtqK+TG1igfIHXni1Bn6doC3rMeV?= =?us-ascii?Q?N5tWGLOSDB+4T6bp15SgKx5HVS5KXT+liZ3vdjK6I9X0wYizT9xOVCqeBP+S?= =?us-ascii?Q?Y9l2T5VcSn4gQ17TqLawDmUr72OxAl/SR3cmM2xI+AV40h6/Lq5bHyh4kfbK?= =?us-ascii?Q?NpFXT5qWwWeyx/8AiK5kchPISkkoiwt7rWkBOoKzRjzMdeIB0lP6jGBI3pvR?= =?us-ascii?Q?Gb8DZ8wa3/Bg+dISeMQ=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)(82310400026)(376014)(36860700013);DIR:OUT;SFP:1102; X-OriginatorOrg: opensource.cirrus.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 16 Oct 2025 10:42:46.3192 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: fa202a7b-f570-4bc1-f930-08de0ca0beaa 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-MWH0EPF000971E2.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: IA1PR19MB7943 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMDE2MDA4MCBTYWx0ZWRfX4xzAMnNPejgS k1LtmQChU0QmZFGXGyfHYBzpcA3GN41WVvLKlYFL5TVnWuLJ905WcD3VMsLalONI5Mrs06UBgJI BKtdR28c7BaWYleHMa12Vn1dIf6BiGXT3YVhmWYRSBU/O9/JP2JW6lNIXYnIGuTksCTVesx/ehy D2LDCAuvCVKLHyW4C9JhUZbl80hgqRT7viG0W5LeoejQN4eufMCTvlbD4hTW4D+yI/4pp244kK0 S2XuT1fcNjMIORjadPzY5Hd2OfwMgUZznotuFgw9FyA4fHj1aHRmcSM8sdbMCEcExR5CpOaGAH7 NdAVDm2IrApOVId9OC52o2OgJVPCJVjKfLFCUNQIgm9xWVqPAEL7o0dzlQqDpI5TY4ssszvVqUj Bdjk53r3BxbOqIhhuqDGbuCLMWCClA== X-Proofpoint-ORIG-GUID: LUUApHcDhFMx-cbLy1ldcA9d5UY27VhV X-Authority-Analysis: v=2.4 cv=OJIqHCaB c=1 sm=1 tr=0 ts=68f0cc2d cx=c_pps a=9413hkbT0mE/MGYjVs5kYg==: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=FQZJoZY4ZGadDpnfufEA:9 X-Proofpoint-GUID: LUUApHcDhFMx-cbLy1ldcA9d5UY27VhV 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 EFI calibration variable. The EFI 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 EFI variable as zero-filled Signed-off-by: Richard Fitzgerald --- 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 09c54b1bbe6c..4c8b84ee087e 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); =20 static inline u64 cs_amp_cal_target_u64(const struct cirrus_amp_cal_data *= data) diff --git a/sound/soc/codecs/cs-amp-lib.c b/sound/soc/codecs/cs-amp-lib.c index 2630ea6a8f3a..3f352ecad3e0 100644 --- a/sound/soc/codecs/cs-amp-lib.c +++ b/sound/soc/codecs/cs-amp-lib.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -48,9 +49,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); @@ -262,6 +270,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) { @@ -271,6 +293,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: @@ -280,7 +303,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; @@ -292,7 +318,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; } @@ -300,6 +326,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); @@ -312,7 +344,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; @@ -328,6 +360,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: @@ -337,6 +373,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) { @@ -344,7 +394,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 @@ -396,6 +446,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. @@ -442,6 +584,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 Sat Feb 7 17:19:48 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 6C0ED2E0903; Thu, 16 Oct 2025 10:42:54 +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=1760611376; cv=fail; b=icigatTMb8QMfmqRQKW1vJCG6XT1zvSkT5V1k1Hzc1PJdME+QHnSqyhKcDqpcjsY9f9kyG2ZTr4meZtKd22uyA8nAuaxWlvZ+0BqN/479MiwxObyE/D/e2wXgtDwUL3ExZad2x+ly9MOYkRe3bVlK76l/yNzPDloTsEXGezZWuI= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760611376; c=relaxed/simple; bh=K/J3XJT94T82s03iJ/QH5gpJFMQXerlCHOxZSOOvAfE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=S8VDF8KgadtOny0yAPbGyRJZNIiRPvk9JlTMoZIm+nBjIRVGzY2RzRzdBfYs/zNUZruJzeMxCybwoMlYiekDlF3XIJuEk9D6Z4H7CCsgtNme/nF+9YF+ImT+pJitcOtlIXFsfOFgzlg/y7lz2z8llwiqeZHoKAQOFeFjEJ6fbQM= 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=I3s/MHVL; dkim=pass (1024-bit key) header.d=cirrus4.onmicrosoft.com header.i=@cirrus4.onmicrosoft.com header.b=bbEdKqwY; 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="I3s/MHVL"; dkim=pass (1024-bit key) header.d=cirrus4.onmicrosoft.com header.i=@cirrus4.onmicrosoft.com header.b="bbEdKqwY" 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 59FMZLZq298642; Thu, 16 Oct 2025 05:42:50 -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=EAMpaSaykDg6ZoklSruubmoRVXxchE5oR6kMFo2sseY=; b= I3s/MHVLyXv770SApBOvOVxnHpkiecdMkget7uKi2zUPEimDueg7gSasWBkjENVS bImGlTu7I43RuP/0pFHTvZKO0c4ojnsFnRXMtFeVGi9e9ZOQqv+kWp3JrAQ+8kA1 j+5B4lIPr19YYJiy1q0mGf1wUsrSD0pw7J1mzaiR/cwcVGz4z6KuwDiviA20HXQD a+AgUYpQVf+dz39eiPE3O2VOipsy4TQZbcnOTt0PCHwdWNqlv3hMEUl7uqnwDwHF cWRUb1O2lG4QRCYT8fHnS4+OHNc2X4JuecWQFahONNvRMGRpmY/K+m225yCvqRXc fLiSx+DFnTsZUKr6sWPrPA== Received: from sj2pr03cu001.outbound.protection.outlook.com (mail-westusazon11022097.outbound.protection.outlook.com [52.101.43.97]) by mx0a-001ae601.pphosted.com (PPS) with ESMTPS id 49t9mhhpx0-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Thu, 16 Oct 2025 05:42:50 -0500 (CDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=H4VNKxwo+i2AgvgQSAxeQW3GblTljD6o0IfW721nfTEW5ROm6tQ1vlcmUrgyEH7jMKyEoL2ZIkWCcJ6t3vWt0BWK52T50sRfhrTaFf4GVO/g3RFvM1U/QNbYQrmUpjNcFKm8j1R2cHORmClQLtmSW9J9+Zr2r4HDorXg+FF0n/OlDv+AY3gzPX/0Tvxnfv8C/0DXe76KJBie2odsjH91DkssHEIXSMoCVKzUlhchSBgNcMmOypIi01cwMbIE111qjsuMFWwsJJXUihFKHg0PjJ8OJpdo6KfAdrEKNy73dCUVqWT6ALmSK15A+IIEPDuA2KbIE2tJZysNKB/5ldvuhw== 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=EAMpaSaykDg6ZoklSruubmoRVXxchE5oR6kMFo2sseY=; b=CQ9rk8pQovb8/VAYfC60P9D98RCqhZAaMKlVIEQxZKlUf3d+yOQbmVSGiWRsNkrU929Ts4II2UBzps7aAn/f0e5vMOCp/muqy9Ta4YwepykQgYs4tYYEvKtIlMwkOnBwkTxnGrlUFSi6sy6L8TEsKROnsM5Pv4ZZ+SEarryO0i7WpnpH4kefecSGvghn2PgStWseV4q7r3qPjZqRBh56gGuVXNami/F8n1UNrfIQPXMdKHUct5BXViCV8OeH7kPKLoBK8wA8RoriEXcJEWGdmiYMTc1td//VgO7fvEkFY7UMrVasicBs6BpXeRo2RtWsxQ0s0PHaKWVhW+aqa6FutA== 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=EAMpaSaykDg6ZoklSruubmoRVXxchE5oR6kMFo2sseY=; b=bbEdKqwYO2ELL4xzs0foRqbvdHU0I/oBp3VFHnE83F0DjA7JFlADwXmxdZvB3hK/NLvgzXlJANX3aa1ddk6uA6cCxnp37RpdujqPFI7hEfQeig3tI3u9JpKPXTbAupDg4dw9+g08WYAHOKs6XsoZji+D7vR3g0Q0WakcgUnmG1Y= Received: from MN2PR03CA0024.namprd03.prod.outlook.com (2603:10b6:208:23a::29) by IA3PR19MB8705.namprd19.prod.outlook.com (2603:10b6:208:528::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9228.12; Thu, 16 Oct 2025 10:42:46 +0000 Received: from MN1PEPF0000F0E1.namprd04.prod.outlook.com (2603:10b6:208:23a:cafe::73) by MN2PR03CA0024.outlook.office365.com (2603:10b6:208:23a::29) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9228.12 via Frontend Transport; Thu, 16 Oct 2025 10:42:46 +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 MN1PEPF0000F0E1.mail.protection.outlook.com (10.167.242.39) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9228.7 via Frontend Transport; Thu, 16 Oct 2025 10:42:45 +0000 Received: from ediswmail9.ad.cirrus.com (ediswmail9.ad.cirrus.com [198.61.86.93]) by edirelay1.ad.cirrus.com (Postfix) with ESMTPS id 120D8406569; Thu, 16 Oct 2025 10:42:43 +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 EA8AC822541; Thu, 16 Oct 2025 10:42:42 +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 09/11] ASoC: cs35l56: Add calibration command to store into UEFI Date: Thu, 16 Oct 2025 11:42:40 +0100 Message-ID: <20251016104242.157325-10-rf@opensource.cirrus.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251016104242.157325-1-rf@opensource.cirrus.com> References: <20251016104242.157325-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: MN1PEPF0000F0E1:EE_|IA3PR19MB8705:EE_ X-MS-Office365-Filtering-Correlation-Id: b20c1af0-724e-47d7-7127-08de0ca0be57 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|61400799027|376014|82310400026|36860700013; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?YH5KLe3g2KlqzhPXdncdwKgHRqa4ZH52jZa8kdsRJgMd98iKkwcxvxfWo3BH?= =?us-ascii?Q?k+8sdnn1r+BczExQM0YKSRxTAmoq0DnAFUkIeyaoBgceQjvIJ3g1SZS6u/ci?= =?us-ascii?Q?Zxedh+lh9aYebDB/C72pm3NGtU8jLZL25ad135xBgx6dcSrxFYZIP2TatUCm?= =?us-ascii?Q?UoL3WSGgGgnt86xQsL/Qgz8B+eLvbRlqgFvvgTOJS3zHQbWqcrVvUYLwzURb?= =?us-ascii?Q?49NNf9/OYG0jXa3Z7YMI6ZDR/5W0LRksxx0vCjjDeCjCpVVR/JZ7Ct1MSwKg?= =?us-ascii?Q?NqIvf39UFp5/Gk5o2ejkjUAiOIt1mZTh4VT60VvHEfscyyRMr+bz1hY00N8w?= =?us-ascii?Q?mcYIBThGctUlcKBpyUPv/pQyLDDkIsquPsFjn8QWj958uid4xKLZd4/dH6lB?= =?us-ascii?Q?e3YCXyiYq4wZHLetw64S3xc1mApHfXk9uR00TDgFnOo/FPClsP4hCuRGImxR?= =?us-ascii?Q?CLkYz8wBbhaOHHJ2WKF53TLi9Y1QN/43/sMBE9/XjAGtllCz2WQGn72Yv32f?= =?us-ascii?Q?osxxlAoItwUpKHyu3w2dP7vy0ESHzvJC4DyrhrV074TATAFYYKni6SQePonT?= =?us-ascii?Q?yp4yCCT0ACMdcKUB89BnvBEiun5wzK/6vuxNQz9vINpf4BYUQuXa5TIV7PEK?= =?us-ascii?Q?eQR9m7HvACDUi7Q1LXBOYnF6q/mQISfvSJQlmG3rbahAOdFssn2Xlor2rsIf?= =?us-ascii?Q?/xDeDCUr/X0NOK8wiaPURN0qeKT+SGmUSq4E6kn1x0GQN5c8vQ5qWPfpyIjt?= =?us-ascii?Q?5+jykh6MUNFVzJ+hPRpRm9qHxoGA9TR6ebaz2RPbLBuAy8hybfy3778KliNM?= =?us-ascii?Q?SudkJXTWmEWho7lNjqH/Ck1Iuntqj5Pzmd2enhIm9cATxok31KnKqUqL5HFK?= =?us-ascii?Q?To7ekdq6Ji7t4n4oQIz5+YwY8t0YGshGaUuCm/2NfdnQigz3fIUzo0fcWeXL?= =?us-ascii?Q?KudnpTAFamw9MkOb83KU2HRoSUeMVFw+YCP34u8ERFqtPtsgpzjk4+SCFsP7?= =?us-ascii?Q?3xVwlB839Wbst69yV/3bv4HAuCv2Ew6BHN6PuMRuJtbFKkQflkIpc60+HyGX?= =?us-ascii?Q?Pwr6AnUFWqH6IGAfEF4g76YHiwJ8aqiUkRt/VOjNvx27I1m1yJlAt+Z133zp?= =?us-ascii?Q?24DWU5OPJjkq0ayqCsnRpapndOQOvYE5AvwndfkeACOSOxaKfcA9VAFApo1u?= =?us-ascii?Q?uKEGTtIkR3qoXZhkFHWf3Msv+a1kkF7JesXht74nce3E5L7FmqSGDLWggEjh?= =?us-ascii?Q?fupvKRvudtO2KLJ/NfXj1uffRsUEcOaWSCuU9RZ9oPtTJxGZAeqlzYLQCW1r?= =?us-ascii?Q?8AMhjcKZJu9SBzX955aJh60o8Es2nxwdZwNIxJONqVNAjAIWWQBkgZQKThEe?= =?us-ascii?Q?sV4b28NwcCuKw0EjkRUB7Dh8IP0+NUiV2UHN70wYIhCF1cJCYg2+kLU7RD8n?= =?us-ascii?Q?ZE1YDrv6Oz2rgXZxbZ2ipzgRL6ScsWVSsFazuruIy/5sLkgZ9QE1hS7EN8RM?= =?us-ascii?Q?jnay8p8eTsr5jx1pxrL/tPa7qObc0eFUrvT3v3viMv8jdpG/z7Hw1oj1CYyj?= =?us-ascii?Q?kBjR+x3BOlDlJU5c61M=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)(376014)(82310400026)(36860700013);DIR:OUT;SFP:1102; X-OriginatorOrg: opensource.cirrus.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 16 Oct 2025 10:42:45.8816 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: b20c1af0-724e-47d7-7127-08de0ca0be57 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-MN1PEPF0000F0E1.namprd04.prod.outlook.com X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: IA3PR19MB8705 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMDE2MDA4MCBTYWx0ZWRfX2cu++q75kYe7 USwKopgWI1l9i8kOUg/PRiIo9W+PtXynBeOn9oTiXx90wAttwVa37c+fDy9LkAO//KLK6jVq89r Z4+3lqbGCR6IoAVYSZ1X6O85BXFBRDBr+qR68yzd6mSga5GwtrmT05yQH3835XZH2EiXwjLaexq XYmBGExuJsdaj36MYLiahRclirHhfoPZXnIz2yUWoG6uPPuyVCQuL8CF3CdaAGcKHEBL2H2el5C jnengM/NGluAf5vxZ0QXU7Rs0341aupBXeR0blz5Qyx1WjhbgaFvV/nxySRmDDMpHfZTvbgr9wE K92ShA5ywDAY8L9LEDXiqWJXT83zm0VDyDwCBE+RmAulADH120507CftJ/W8U3NFIfCdUrLHE6a eug2p9/D3L92Q8S03WuFC/g9XKb2gA== X-Proofpoint-ORIG-GUID: h5lDUkZ61hF24To5Qi2j-ZJRn8E2OFJo X-Authority-Analysis: v=2.4 cv=OJIqHCaB c=1 sm=1 tr=0 ts=68f0cc2a cx=c_pps a=V6sUqnxsgDMRanywjcdTsw==: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-GUID: h5lDUkZ61hF24To5Qi2j-ZJRn8E2OFJo X-Proofpoint-Spam-Reason: safe Content-Type: text/plain; charset="utf-8" Add a new command 'store_uefi' to the calibrate sysfs file. Writing this command will call cs_amp_set_efi_calibration_data() to save the new data into an EFI variable. This is intended to be used after a successful factory calibration to save the data into EFI. On systems without EFI it will return an error. Signed-off-by: Richard Fitzgerald --- include/sound/cs35l56.h | 1 + sound/soc/codecs/cs35l56-shared.c | 19 +++++++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/include/sound/cs35l56.h b/include/sound/cs35l56.h index 4ed738615021..b3770285261c 100644 --- a/include/sound/cs35l56.h +++ b/include/sound/cs35l56.h @@ -314,6 +314,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 dc6e49e3421a..27fb2f9b83c5 100644 --- a/sound/soc/codecs/cs35l56-shared.c +++ b/sound/soc/codecs/cs35l56-shared.c @@ -1101,8 +1101,8 @@ static int cs35l56_perform_calibration(struct cs35l56= _base *cs35l56_base) ssize_t cs35l56_calibrate_sysfs_store(struct cs35l56_base *cs35l56_base, const char *buf, size_t count) { - static const char * const options[] =3D { "factory" }; - int ret; + static const char * const options[] =3D { "factory", "store_uefi" }; + int num_amps, ret; =20 if (!IS_ENABLED(CONFIG_SND_SOC_CS35L56_CAL_SYSFS_COMMON)) return -ENXIO; @@ -1113,6 +1113,21 @@ ssize_t cs35l56_calibrate_sysfs_store(struct cs35l56= _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 Sat Feb 7 17:19:48 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 16F84299A81; Thu, 16 Oct 2025 10:42:55 +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=1760611377; cv=fail; b=nr8vh7aX+59BG4bfQTi8lLO6wwdanX3B92UPuv/T1cmrVqoFTtf2KRk1wgrL5LvkfMLBsM5ztlsIrgUXv9sjOjfiNJzbnJX3IWGjwXKQzB8Gl5dDVmYcj3xgK/hiJnOzo6ZMSPdZ0KkrhH7ZO9GMjjZhReKNA7vxBt4oE/iu75E= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760611377; c=relaxed/simple; bh=EhhVUJvM+hFWbHiAu0ArIVFzvM6wszKHbocZYNdwRMM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=maobrGHTU72fCQOdLDuMLpJ1gm+dXWlQ5ZzHJ9XDSaPLlsPHZwxobSgxFdigRQj9VG4ORkp7Y3vVjCGhn0BLdSx/PwASdNHj4yJ96SLEWLReLVDP3ieiUIO3Yy90FZ6OLb9Yp1QWrfFmYO3+GbUQUSndOfkrU/QhZ+J0wyy2bo0= 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=IvEHojv5; dkim=pass (1024-bit key) header.d=cirrus4.onmicrosoft.com header.i=@cirrus4.onmicrosoft.com header.b=z1HlE9b/; 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="IvEHojv5"; dkim=pass (1024-bit key) header.d=cirrus4.onmicrosoft.com header.i=@cirrus4.onmicrosoft.com header.b="z1HlE9b/" 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 59G8fDdD2477160; Thu, 16 Oct 2025 05:42:52 -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=mrfh3MlKc8P3eMenEOCLL5AQM+xNt8AaEnwlp/iQqZQ=; b= IvEHojv50wZ+KpGH0AHeKA5y5cxT5uwgWfvttUDhRpH4ifLKP6OpFssh6UyrmtIe tPbFHzWWulm/AcSnG0SUErHBTSIB9NjqQCYQrnEg1GstKtddQqxFbRKDeFFtX5EK OLjTggrJI4kFiEs1IsrFUeK8ZUi3qAObFSMzy8LEFhjepZyp2Np3x0PESRNOZlrd 8JLWSZOo2DkYJMirBM+kMCpntWO6MAnJMiqL8tEX4J8SqY0PZDfHaYkDbEJbFfLe vpNc/xeEDcL/cymCARPKugtmSQs2UCqtgbAZwVb9VWBR10vjJMbJV99Mj/eiip+v 1XV+NjKBrOZCPLDUO2F9aw== Received: from ph7pr06cu001.outbound.protection.outlook.com (mail-westus3azon11020073.outbound.protection.outlook.com [52.101.201.73]) by mx0a-001ae601.pphosted.com (PPS) with ESMTPS id 49t9mhhpx4-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Thu, 16 Oct 2025 05:42:52 -0500 (CDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=sbcoJ2AlcnlM0Q7jpKL8lOcqBHQVy3TvdqO6a1GN0ltqdrGjKUUuPVmG20ePD3Kgnf+MFN2SEIVk02NTtsMWZMYIPEWjcnUOiSzATUBjdgZQtMKdsGm+6nsWXDTKICH2Sf1u9e8FZiEEzYnvfW/+eMx8fF7/bXgS6ynjhKwCMERTPMFAVNljF3D2zXfb82CK4v/IP9O9ANHsb5wPNbcmoD/HfDJNz5zfPRT4SR0kDAEj4v8BsjE1ce0C6LUxdW4oZDo2n9CMHGQ4vPL0es182h4/oikQ1zpVUIKqFakG9mSq2T7jVDhqQUpunAC4hyOSx1O43U4HC2BOUJJ9+t9KkA== 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=mrfh3MlKc8P3eMenEOCLL5AQM+xNt8AaEnwlp/iQqZQ=; b=aqlCpjfodj0wnbMa/RPx51+VxYypHxbaGWx8pbKtsFvjLUfe3CUUhvyxD8jjBEypbNLzYxO0QNHpWit+GMfjhA1kFBaqf0XVNAJp1Ss3CxYXYcI220cxX/uS28zrBk2oH52pjG2/hUKFInHFzzvxWyh7vLAxcLg6IjPfMj98T4SvXz7LTpSePFs3SbjQoVFEo3YTRZCCxe73GMeqvU3MWS3yWsPFGI6jK6D6kS1HaxIlkgvoO2GCMs2VqhBcNSVPMnlQU4wMli5TTDvZPV/9hSz3euU8l0qunTjqLOi9GLbzrAa7AihswZ5xWPmcWHgiTKDtPSFawURvTwA30Ne6hA== 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=mrfh3MlKc8P3eMenEOCLL5AQM+xNt8AaEnwlp/iQqZQ=; b=z1HlE9b/bEVxtkMlhURNLIztO9GbwS6hdawKScR/W4XvCgmxwb7UCDjmPDRTo/belGtVKlZkq/4d8Cr40o+vB1JGI2WXsXfxmRai9lixHWks5ZfkKzuhKJinIB+/TuvklAQ1Go6sDWm7OJAE9i6n7qKbUx3QaJP99rrRCShvGXc= Received: from MW4PR03CA0274.namprd03.prod.outlook.com (2603:10b6:303:b5::9) by PH7PR19MB6506.namprd19.prod.outlook.com (2603:10b6:510:1fa::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9203.12; Thu, 16 Oct 2025 10:42:47 +0000 Received: from MWH0EPF000971E8.namprd02.prod.outlook.com (2603:10b6:303:b5:cafe::13) by MW4PR03CA0274.outlook.office365.com (2603:10b6:303:b5::9) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9228.11 via Frontend Transport; Thu, 16 Oct 2025 10:42:47 +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 MWH0EPF000971E8.mail.protection.outlook.com (10.167.243.68) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9228.7 via Frontend Transport; Thu, 16 Oct 2025 10:42:46 +0000 Received: from ediswmail9.ad.cirrus.com (ediswmail9.ad.cirrus.com [198.61.86.93]) by edirelay1.ad.cirrus.com (Postfix) with ESMTPS id 1620A406578; Thu, 16 Oct 2025 10:42:43 +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 05154820249; Thu, 16 Oct 2025 10:42:43 +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 10/11] ALSA: hda/cs35l56: Set cal_index to the amp index Date: Thu, 16 Oct 2025 11:42:41 +0100 Message-ID: <20251016104242.157325-11-rf@opensource.cirrus.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251016104242.157325-1-rf@opensource.cirrus.com> References: <20251016104242.157325-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: MWH0EPF000971E8:EE_|PH7PR19MB6506:EE_ X-MS-Office365-Filtering-Correlation-Id: e894d21d-be29-4ce1-f235-08de0ca0bf0a 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?5vSP0s9huQ4xIbJ8QxVpLK2lpgsIq3pUrLWvuBqCi/ZCEVjZTqnlgmoXz6Dy?= =?us-ascii?Q?yHYBnj+zHviddAHy/z01f7WnyAcHcvN48Xu8QnejMv6+Ast7Ik4IZzH7rFH8?= =?us-ascii?Q?qs4xgMJYQZchXg/1dA8qyqMQonH6TWTKE1zgid+8VOQ4o17LzZPBmz8uK9Tz?= =?us-ascii?Q?Xlw/D+wnW3WM/snnoPnap5gRYcr92bN+iljelqoJR4I7b3tPbTtz6JuFigQc?= =?us-ascii?Q?jkHkc9Fe026LaR764UYU+2Dcygor2Pz1xPnTYkMCkCFOyVsKkuVdFHYBFuKS?= =?us-ascii?Q?BA0zNMfUk0OjE54OBip1k01W92jh2YeI6whlRiHmpViQPrjO5z4sAdwrcp56?= =?us-ascii?Q?/99qGiNWfGrCbR2AcgzrzRsWBSNtZjXKOSaalj9Ckf86aAcLpVlXdfDAPoWu?= =?us-ascii?Q?aoA5vkdtZtJ1mSULfAAfkqYgCN2h08sWfLQa7KtnNZhIKm+/cbXJuRnYVxuq?= =?us-ascii?Q?QhUOkR2RBhjNssGsTXXcER/YPMZjhyg62diGKD4RfZVE0zczm/s77S+fDGV6?= =?us-ascii?Q?/YiJwYCh6XOrA/H9PKZ88AYQgyIw+BcUQb3yNtHt0aAj88dSiYZiPesKi22N?= =?us-ascii?Q?5MF7tD9pY0S7b/XYA4VkMhYOeEULh/iWC7jM1Sv40R7KzU/cRnrcKHAy1aCB?= =?us-ascii?Q?IlmnrlDuzxXP+aZkIwgm9vCHWyPH0L4XlkUrmV83GdMpb2sYmbkLsRnp4PgY?= =?us-ascii?Q?Y9c8fTVSU3fnJxiVRa6PPkiEywOgzNp3wFxp4HEGba8Usgm2Vi8/6iwdw6Y6?= =?us-ascii?Q?gsam5WBjJyfRQp4/zIJZjz6E1kMo+BTXlLdT7RNo4yvLK1pjSYpkf5bIF2W5?= =?us-ascii?Q?37ezMR4qTxvqGesQblff6fRfRoJFqACbBw1Th02b5G+AAXf+nZyRJTPCXt9O?= =?us-ascii?Q?qt2aBGJgvkueyIAocbil0iaD5a6trT4rXr5+uLHZ6f2BZHMrNXyho/VSTf6a?= =?us-ascii?Q?YR5rDYjTmtoEJrslkr5BJyPdNYxSNoswy9H4bgh2QAHpcx5YlVBHfjq1G2BT?= =?us-ascii?Q?uxlcvYFyQpdF07l1a4UXnbDtvVgaHUxgDqptHhHsh92ZJ4aHArVkPq5TbIA4?= =?us-ascii?Q?Hc3iJ7TFmPoA6/W2k2m572WDPxpj3ffC0oM9VJqVcO3plysf9acjSeglQ+CJ?= =?us-ascii?Q?MdFXZq5DWMtwI94eFHEwBRJy6yHhJ8vVig/NM7gen3qkExjEDmx1nQu798gP?= =?us-ascii?Q?DlyI829ZnzM79oX2HkoXy1tWtARsZYPiNRMMIfL6P3cVL06pXF1x0I6Uhy/R?= =?us-ascii?Q?5uSs1CAc5QmqaE/qXlFAiuUBsrcz9SkxzQ2e8gDaPniym0blSTm3QyJIowyQ?= =?us-ascii?Q?2RcZE84ErlT0LqgRTAHQyvBfMk163duXNfYHKrjdLszYDXJV9pdo0BkIGKCU?= =?us-ascii?Q?uC+XkR6nc6Cl2Z+wGHyKNBU+/IiTb+mndF+rLnGGaxlLz98NpaK3Jw8CZ94n?= =?us-ascii?Q?TpVdR/rQfWswNwZAUBQBGn0c+oZx0kJbZOjih+WG7x4wK9NRuWARjBVp+eDt?= =?us-ascii?Q?wTmlpPkw6yH90XXXOxdajxN3wRZV1by1l/S46n+siwxARRcGdkQAyt3+BOge?= =?us-ascii?Q?2Y79VEsJWvqoyYCPs5E=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: 16 Oct 2025 10:42:46.9375 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: e894d21d-be29-4ce1-f235-08de0ca0bf0a 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-MWH0EPF000971E8.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH7PR19MB6506 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMDE2MDA4MCBTYWx0ZWRfX3SUOJ6fVZonr eO4sTnsKQjgelZ6PgOrygXMzemexBxapVNDClGzIdRXAunrsRP/ChecImJCH2y6Q9IIwpYWbJM2 nH9iTWJ6/HkquRFsp1+HeONMMUapfrU0Uq6ilkDUMv53lchl3X7iOn67aAeT/1ScpC5LmM4qTTZ HHotB/8/RCx3c25wAQGe22uvFtvDod2s3oM/4hjmKKIcqCZx0mUGHbTOwFoFr3srD7Mm2QQW8/z lhkum2/G68yIgeU0Js7VTRHiDR4I+rvrqZWoM9MVpwKXil/F4Fh28BlH148oGvmjraXjCkIyyrd VGNZwzShiOoaVtWalSZyfccXtrtwh74sj0MBXzLExM5U2w2+AW4vsACkdO9VvKeF3j0rwfiLZME huIeuAqxdKHQUKhtDWgROLPGNotx9g== X-Proofpoint-ORIG-GUID: dZXpJeGJgUuVFgwUrynO4_fN8YQc2Cac X-Authority-Analysis: v=2.4 cv=OJIqHCaB c=1 sm=1 tr=0 ts=68f0cc2c cx=c_pps a=kTz8n/oXhugbiFfz+wFpMQ==: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=rJdgk25NQal2zjiPUrkA:9 X-Proofpoint-GUID: dZXpJeGJgUuVFgwUrynO4_fN8YQc2Cac 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 EFI array in the slot equal to the amp index, for compatibility with the Windows driver. Signed-off-by: Richard Fitzgerald --- 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 4a1bd934887a..19baa8be310d 100644 --- a/sound/hda/codecs/side-codecs/cs35l56_hda.c +++ b/sound/hda/codecs/side-codecs/cs35l56_hda.c @@ -1179,7 +1179,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 Sat Feb 7 17:19:48 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 75C4731D376; Thu, 16 Oct 2025 10:42:59 +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=1760611384; cv=fail; b=XLtjBwZnZ+HSdBrVTDDeHIjA9+SVHFuwje/+IevAz8xPDFqoMBXABG68TCmTfxZrI78ExLAN/f5WZdnxki1caGYo8xo4BfpvlX6uFNGTFE+4Vkyu+SRHIXSYWqw1AFjTbocC2zCwcIPUshmcovhDeWbXkNCdEirKib55v/KkSPQ= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760611384; c=relaxed/simple; bh=iTlyfBeBKkWEIgGGChA87p9CXvrzoxRyD49JEfEP6RE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=tWxfO3yR+9FIRgL+X45++nc0rlbNjVgMrNrHPMpedp+XsQR+XfT7ZqzQdkIvIQkTyfhpDBTrFGp1yJ5GTSFjQkxsEkuK9DCfzgYeHqxybAend4jRXA08v+D9/RxthoKzB85FInQmVomfkUHvN7S/I9M1epbqX9AhYd8DDhu+kLE= 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=IBMgYr5b; dkim=pass (1024-bit key) header.d=cirrus4.onmicrosoft.com header.i=@cirrus4.onmicrosoft.com header.b=tT8kWRXz; 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="IBMgYr5b"; dkim=pass (1024-bit key) header.d=cirrus4.onmicrosoft.com header.i=@cirrus4.onmicrosoft.com header.b="tT8kWRXz" 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 59FN6m5C298627; Thu, 16 Oct 2025 05:42:52 -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=ZlpCYxheRBHBsiHQt7cb5QKkPd4eQ8HeF6vgbA9IN/8=; b= IBMgYr5bX7kukhJfmFeQ0f1HrwKZQW6qT0DKQSz5ojLMWB5FKNlXl3HYjXtNccjn bOuWTQoL0kzDF1ReXtxMIPX3I33OFsBiCodAXwlaqvscWneKLKxsuftFzK8EWmwT qa+fu22L3T7HTkg1j1vLZv3Qh2AWZE4alhBPaKICn16wopPGyARz44Q7BUKYcp+z 8x/rVMhlnNn4dafKVYLWByPmcQ4H5+89yLjC5tARRPodWC9/Yj/ObugIU/8Jzaj9 dxKskyHZ5OI9iuu7u0/0xtQKVPsMDsuuazJsQJElSXpqPvECD7jA8muLT3JvY710 DRUBb/+zN14ubN+C19l2HA== Received: from byapr05cu005.outbound.protection.outlook.com (mail-westusazon11020128.outbound.protection.outlook.com [52.101.85.128]) by mx0a-001ae601.pphosted.com (PPS) with ESMTPS id 49t9mhhpx3-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Thu, 16 Oct 2025 05:42:51 -0500 (CDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=lHq6Z3Y8hRNMuy4c8KDUJijf0bZ51w3q+LIcfq8wcl9bIaP/g8IvRaPGexX858WiLBnnsHnZggqubN6UKfpdLCvIAF4lUddUH+0g9DXsGES/E95tGgWQZTkhs0VEmufbwHfIBYXr1OrhnLwjyR8l04bRfVOShhZCOPQpR9Y14nF1K+FGzzk67+5Ivs7GN0RSgkAAd7+QrJsQi49lI+JScoR2kbMYI2hI6f0goLpNPG7MGazLsnHYVl/0hi9cQI4zVvR4h2+XwXh1cv4K+S7H5sbaXKu45x97OL5s5L/hg+WDitcFo2iWU9z38YbRGxQbiiKckL0fP/kz5g8sZPdg8Q== 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=ZlpCYxheRBHBsiHQt7cb5QKkPd4eQ8HeF6vgbA9IN/8=; b=XnQ3lsPqNs88VDwH/SV7Sy2Q3zZCQhY8bMfeKE9PFiVqqYdaGxliQNk8I487PskrSvPDhKy8fNahvkcSQMbQpxIroUxzFYCX554NsPn/qyq1m5Xa5EcsaFNOqjcjSIO4aCzi2Oo92jz+umMFGhsPy0a1WVhWi6jUv7v87+rfEb3vO68VwM1chYsORvhpc9mHwiDEdwb1JCJTTM4OGlt1GkUnzZhPI2wVsAstl8IYdFR1r7vhq2dfoLy8QtnQy7GLoUaR2lP4ex9xtklkPEx8cMbeksgZVgMyZJuhVbmNVByn2IKMdGl1+gDnb7UGvsYKoPYe4waa+/kINws7LfMIvA== 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=ZlpCYxheRBHBsiHQt7cb5QKkPd4eQ8HeF6vgbA9IN/8=; b=tT8kWRXzjAR3FzKynITa/NmlecwsmBpUnVQji+8RxhDfucHn+mTBXUx9ElEkGXPB5PBwkt4dTHnN4I9M+Uho2qxtsElJRP5OFHyfWZSeURQIKj5MV6xc95mtwnV+uNLm7bjKGFe/rE1n2tb2eYpFfK01tvA4gohtIb3NE1riAbQ= Received: from MW4PR03CA0078.namprd03.prod.outlook.com (2603:10b6:303:b6::23) by SN7PR19MB7041.namprd19.prod.outlook.com (2603:10b6:806:2a8::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9228.10; Thu, 16 Oct 2025 10:42:49 +0000 Received: from MWH0EPF000971E4.namprd02.prod.outlook.com (2603:10b6:303:b6:cafe::52) by MW4PR03CA0078.outlook.office365.com (2603:10b6:303:b6::23) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9203.12 via Frontend Transport; Thu, 16 Oct 2025 10:42:48 +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 MWH0EPF000971E4.mail.protection.outlook.com (10.167.243.72) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9228.7 via Frontend Transport; Thu, 16 Oct 2025 10:42:46 +0000 Received: from ediswmail9.ad.cirrus.com (ediswmail9.ad.cirrus.com [198.61.86.93]) by edirelay1.ad.cirrus.com (Postfix) with ESMTPS id 1F6A4406579; Thu, 16 Oct 2025 10:42:43 +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 0A05D822540; Thu, 16 Oct 2025 10:42:43 +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 11/11] ASoC: cs-amp-lib-test: Add test cases for cs_amp_set_efi_calibration_data() Date: Thu, 16 Oct 2025 11:42:42 +0100 Message-ID: <20251016104242.157325-12-rf@opensource.cirrus.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251016104242.157325-1-rf@opensource.cirrus.com> References: <20251016104242.157325-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: MWH0EPF000971E4:EE_|SN7PR19MB7041:EE_ X-MS-Office365-Filtering-Correlation-Id: af00d366-4937-461f-c63f-08de0ca0bf06 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|36860700013|82310400026|61400799027; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?1wTnSh+qt+kF0ManJlj+FhMTLahuG/bFT4DSfxug5gyA8GQTC/dFX9TkdJir?= =?us-ascii?Q?TK5lU8ncluniqH4brPsZNMew9v5gI1pua8nuaVhLBTYv+41AhCKEjS5VXIxc?= =?us-ascii?Q?pD+iGz9ExKl2P0oMlnFDagtmjOIEk4QQRBikxDiEDMWEO1Dm4B90/9u1si4X?= =?us-ascii?Q?J1mUkl4clkg82zsLK8HU/6tpQB6JcrhNzSo7o813sW2eyQSTfcco48x08Z8p?= =?us-ascii?Q?iToih2pvIU1MzF/4rT1bXfBEFhNHba2Pn7kbShbF3+7FKg4Xz+HSbKZCCRbK?= =?us-ascii?Q?zQM0VZor9snm2jAOXsC2kA+85dwiUCrLoUZ9+UwUam43x11VNZzpOP+hK38Q?= =?us-ascii?Q?5u4IwUL8JOMMBXeXComXKyahUJS1XHLKBQRNqW8EoAJvQ23Spchrh6a8fK/c?= =?us-ascii?Q?M6j56RxLgZ5x6ZRtUNoZ/2z5pdexOjQpJ/7N9EPuIUl7JUj2APST/X80kQJa?= =?us-ascii?Q?jHfnUTT59YsfKI0U8Djye1f3QqYhUYJE8p3UxOMxAmcEy4SDncSijX3IZ9RL?= =?us-ascii?Q?A5xKh0dMhnVy5rUbQsTGmJHsygt07Djlflwa4cr71I84JpKLde6unjlSTVfF?= =?us-ascii?Q?/bXjvZaryG/gH9MLpjaUm0SLuWxxiGVwTxZR9oRo5N/oMzZBgyu9oZhlY5x1?= =?us-ascii?Q?+qKjLNjlWfV5xhuhZ6Yo+ffSui7p63AuIWjVesXleYWYdTAbN3J9/kIWAzRQ?= =?us-ascii?Q?fM8owm/5k0ls+GjNKRs2hQCmDGWo3tQfI//+8jZFKLpi4x/F7FVmSFJ11Wtz?= =?us-ascii?Q?z8ddwAcAE0NO3o8lUlcEUiWfxrWKTnFYoaLsOmAkZTuUNK2l9F9QJ/L04eJY?= =?us-ascii?Q?eXtu0ery6tfLxVo3Iy83rofflM8FTUCjpDq7pOxO+8CNsRnQuKXQntcZzV74?= =?us-ascii?Q?4sbb/Y3QHQ7+JSedScZqyKvE357MMFwWMwiFKF5fc4sbEbCFRoouyA4k+81Q?= =?us-ascii?Q?bCuOn/NtffW07ZY/VdhMQF5GizUsP76AiTUmuv4429PWqQFu8izgUf6yW3Qs?= =?us-ascii?Q?Dou6V25sjZ3y7w6S/Cp7fG7iVwqrZXs3ZUKEnjtvsUiC+JrtIytPtHHqrYtQ?= =?us-ascii?Q?sa4rC3x/LLOs1qmLrUTun6S5Y5oBFYnkYCHivcxX56w72XPob6VbWfGZTAI3?= =?us-ascii?Q?qOXusF+YetAkP13le/yBGnolyNhUAoRmI0vLfi66aL3zwGWDcF9iHDW+c4AD?= =?us-ascii?Q?UpBzxIRf1I7G1hmP7wCYoPqRLtAGSy6R51Qs11VM1byMiUrIWXrJZ0RuIgfO?= =?us-ascii?Q?21gpxVUgB9FU5qNtZZaiJK5qNy18nxLZV++bcaIOxwldMDC2FFRflr3XXueW?= =?us-ascii?Q?RiacHQw5sOGlPyxoOszAFDRQw1laTAAdQ1Mu5XwdeB0fdl2Hnqn+QzjvOQjT?= =?us-ascii?Q?pW23XcpyU0Nz1xQDkn8slJZ/lzWqlyywL+3qtYqK7PFZTBP021IHQswAFX4O?= =?us-ascii?Q?KIX3rQfaeXJxSraTvhRxnAI79onqTLm+KICmInK8smQ7+fp4gGiXV+KjIWxK?= =?us-ascii?Q?HUDt+NS4/oUU2nEU3VfrFGH8jnx6KDvFMRiSzgey+92xPQsm1CkszR33enzM?= =?us-ascii?Q?39O8CskH/fxKTVxH6vg=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)(376014)(36860700013)(82310400026)(61400799027);DIR:OUT;SFP:1102; X-OriginatorOrg: opensource.cirrus.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 16 Oct 2025 10:42:46.9106 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: af00d366-4937-461f-c63f-08de0ca0bf06 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-MWH0EPF000971E4.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN7PR19MB7041 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMDE2MDA4MCBTYWx0ZWRfX+INo7OdaN2JR m9Jt13FaQW/G0htQi/G7hHYXNByZ7upTcARH0VEv6JpmCJphoOAAMPYCoeZS4oK7SP71+TNlskR iN92RbEe4jdkXnQWmcjfc7Das+mEJ16xYDWzJlTHJeBYvIDAIpcXLrFIOM3xyjKxACiXbGj40gV SOdChi4mRUTQJUTVDHC7BGKMpbM9PwAHjp5PfukEBIOcuReSbj10bz5nfvefXGQEJ3T3kZhL+8K LS8DQSqnMCS5uzkmWT3GiZvKre2AFKrH+35MzIdcRn48jPWQ3u4XGcuAYEc730Wnm6aKj/spgMh mWtn8ieHwwXK9ciU9KbYisEhfKjTIrUhQpuotYz6nzvfeSQBQlMFA3mZevtPvBzGOgU08jiuJOp k8PjuCHdsS2n3T4a1HpQfIH5qaNkOw== X-Proofpoint-ORIG-GUID: cC16SFYIWUMdcIQkoFDPPgV9W7JwqJHO X-Authority-Analysis: v=2.4 cv=OJIqHCaB c=1 sm=1 tr=0 ts=68f0cc2b cx=c_pps a=rJ76FBf8UdibaoD+N2q2jg==: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=ulGInPhhc-9duvULAZUA:9 X-Proofpoint-GUID: cC16SFYIWUMdcIQkoFDPPgV9W7JwqJHO 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 --- 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 4c8b84ee087e..8eee4ce9eefe 100644 --- a/include/sound/cs-amp-lib.h +++ b/include/sound/cs-amp-lib.h @@ -70,6 +70,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 d3419f48297e..7fa6aabc746a 100644 --- a/sound/soc/codecs/cs-amp-lib-test.c +++ b/sound/soc/codecs/cs-amp-lib-test.c @@ -20,6 +20,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) @@ -28,6 +32,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 @@ -36,6 +44,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 { @@ -49,6 +58,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; @@ -69,9 +92,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) @@ -199,9 +228,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 @@ -223,9 +251,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; @@ -790,6 +865,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; @@ -1073,6 +2434,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 3f352ecad3e0..1c53328d7165 100644 --- a/sound/soc/codecs/cs-amp-lib.c +++ b/sound/soc/codecs/cs-amp-lib.c @@ -701,6 +701,7 @@ EXPORT_SYMBOL_NS_GPL(cs_amp_get_vendor_spkid, "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