From patchwork Wed Nov 22 06:35:37 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Chiu X-Patchwork-Id: 1867166 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4SZs4L0ZRtz1yRg for ; Wed, 22 Nov 2023 17:37:38 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1r5grO-0002WB-S6; Wed, 22 Nov 2023 06:37:21 +0000 Received: from smtp-relay-internal-1.internal ([10.131.114.114] helo=smtp-relay-internal-1.canonical.com) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1r5gq2-0001yo-53 for kernel-team@lists.ubuntu.com; Wed, 22 Nov 2023 06:35:54 +0000 Received: from mail-pf1-f198.google.com (mail-pf1-f198.google.com [209.85.210.198]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id D3F4D3F471 for ; Wed, 22 Nov 2023 06:35:53 +0000 (UTC) Received: by mail-pf1-f198.google.com with SMTP id d2e1a72fcca58-6cb9dd2ab8fso3651918b3a.0 for ; Tue, 21 Nov 2023 22:35:53 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1700634952; x=1701239752; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=3iSW2mJZtIO27B633rAwXy9vr6YALflbQV3EeZlKzZs=; b=vzyE9uqEltNrn4dv3IbCBdY5hwUJ/i3dWZR6f1ictUCF1qAE+ZVeAoFizXtfnX9yA6 fz5NA6+gYjkjW2844LmcPeuChvrC7YblvjMWexaLwfzNArC3e2mu/4FZ84OKuam3Uggr plAJ5EvpMD08Q2eJrZgf62SKcI/GjRoINO0TUnFPXafKIHSA5MpS0csJziprYx4wGNi3 onWRDMVroxnmSXjjn1YWZpeKhEPEpP2QXbMsAuKj15HJFnNbUXFN0eJXpLavnAmr4+Ie xWJipaIUfgzBc2ucUAwK0KdSUtEwbal6w5osvvOvpq+3/uRJMZzkHQqMOTRO+Tl7mtZx 0YqQ== X-Gm-Message-State: AOJu0YyIQ6G/RJo0ctjRdSguRHeSTJlcI3ChLK2gBv2NmduSyubaDGEi icrWbsZENhJVtl4zGxZYP4zg+U8mnWcreLzdAnlTp38Z4R5aT7GXZaTABelIUIVhC66pHxu6HuD BDDEAVTdyGI/vQxJ24k5vWTgr8XgvOe/hblhxorOSgJYlKZaRwg== X-Received: by 2002:a05:6a00:84b:b0:68e:2f6e:b4c0 with SMTP id q11-20020a056a00084b00b0068e2f6eb4c0mr1374719pfk.28.1700634952145; Tue, 21 Nov 2023 22:35:52 -0800 (PST) X-Google-Smtp-Source: AGHT+IF4kFLMC5uc/rNbhrkz9UU821edmocXekSEpcSRQlialmYWZZID8s02du9Gdko8qlm/c7YArg== X-Received: by 2002:a05:6a00:84b:b0:68e:2f6e:b4c0 with SMTP id q11-20020a056a00084b00b0068e2f6eb4c0mr1374704pfk.28.1700634951606; Tue, 21 Nov 2023 22:35:51 -0800 (PST) Received: from localhost.localdomain (114-36-219-155.dynamic-ip.hinet.net. [114.36.219.155]) by smtp.gmail.com with ESMTPSA id z10-20020a056a00240a00b006c31c0dfb69sm8966360pfh.188.2023.11.21.22.35.50 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Nov 2023 22:35:51 -0800 (PST) From: Chris Chiu To: kernel-team@lists.ubuntu.com Subject: [PATCH 06/10][SRU][M] ALSA: hda: cs35l41: Run boot process during resume callbacks Date: Wed, 22 Nov 2023 14:35:37 +0800 Message-Id: <20231122063541.11346-7-chris.chiu@canonical.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231122063541.11346-1-chris.chiu@canonical.com> References: <20231122063541.11346-1-chris.chiu@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Stefan Binding BugLink: https://bugs.launchpad.net/bugs/2042060 During initial probe, after reset is asserted for the first time, the driver goes through a boot process to ensure the amp is ready to be used. This involves verifying a boot flag, as well as verifying the chip ids. This is necessary since it is possible for the amp to have been fully reset by the system suspend calls. Signed-off-by: Stefan Binding Link: https://lore.kernel.org/r/20231026150558.2105827-5-sbinding@opensource.cirrus.com Signed-off-by: Takashi Iwai (backported from commit 881b7bce0c250386680b49b637455d31238a4b30 linux-next) [Chris Chiu: ignore the conflict of dev_err_probe and dev_err] Signed-off-by: Chris Chiu --- sound/pci/hda/cs35l41_hda.c | 105 ++++++++++++++++++++++++------------ 1 file changed, 72 insertions(+), 33 deletions(-) diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c index fadac1603a9a..1d47779be81d 100644 --- a/sound/pci/hda/cs35l41_hda.c +++ b/sound/pci/hda/cs35l41_hda.c @@ -665,6 +665,34 @@ static int cs35l41_hda_channel_map(struct device *dev, unsigned int tx_num, unsi rx_slot); } +int cs35l41_verify_id(struct cs35l41_hda *cs35l41, unsigned int *regid, unsigned int *reg_revid) +{ + unsigned int mtl_revid, chipid; + int ret; + + ret = regmap_read(cs35l41->regmap, CS35L41_DEVID, regid); + if (ret) { + dev_err_probe(cs35l41->dev, ret, "Get Device ID failed\n"); + return ret; + } + + ret = regmap_read(cs35l41->regmap, CS35L41_REVID, reg_revid); + if (ret) { + dev_err_probe(cs35l41->dev, ret, "Get Revision ID failed\n"); + return ret; + } + + mtl_revid = *reg_revid & CS35L41_MTLREVID_MASK; + + chipid = (mtl_revid % 2) ? CS35L41R_CHIP_ID : CS35L41_CHIP_ID; + if (*regid != chipid) { + dev_err(cs35l41->dev, "CS35L41 Device ID (%X). Expected ID %X\n", *regid, chipid); + return -ENODEV; + } + + return 0; +} + static int cs35l41_ready_for_reset(struct cs35l41_hda *cs35l41) { int ret = 0; @@ -762,6 +790,30 @@ static int cs35l41_system_suspend(struct device *dev) return ret; } +static int cs35l41_wait_boot_done(struct cs35l41_hda *cs35l41) +{ + unsigned int int_status; + int ret; + + ret = regmap_read_poll_timeout(cs35l41->regmap, CS35L41_IRQ1_STATUS4, int_status, + int_status & CS35L41_OTP_BOOT_DONE, 1000, 100000); + if (ret) { + dev_err(cs35l41->dev, "Failed waiting for OTP_BOOT_DONE\n"); + return ret; + } + + ret = regmap_read(cs35l41->regmap, CS35L41_IRQ1_STATUS3, &int_status); + if (ret || (int_status & CS35L41_OTP_BOOT_ERR)) { + dev_err(cs35l41->dev, "OTP Boot status %x error\n", + int_status & CS35L41_OTP_BOOT_ERR); + if (!ret) + ret = -EIO; + return ret; + } + + return 0; +} + static int cs35l41_system_resume(struct device *dev) { struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); @@ -782,6 +834,14 @@ static int cs35l41_system_resume(struct device *dev) usleep_range(2000, 2100); + regcache_cache_only(cs35l41->regmap, false); + + ret = cs35l41_wait_boot_done(cs35l41); + if (ret) + return ret; + + regcache_cache_only(cs35l41->regmap, true); + ret = pm_runtime_force_resume(dev); if (ret) { dev_err(dev, "System Resume Failed: Unable to runtime resume: %d\n", ret); @@ -843,6 +903,7 @@ static int cs35l41_runtime_suspend(struct device *dev) static int cs35l41_runtime_resume(struct device *dev) { struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); + unsigned int regid, reg_revid; int ret = 0; dev_dbg(cs35l41->dev, "Runtime Resume\n"); @@ -864,6 +925,10 @@ static int cs35l41_runtime_resume(struct device *dev) } } + ret = cs35l41_verify_id(cs35l41, ®id, ®_revid); + if (ret) + goto err; + /* Test key needs to be unlocked to allow the OTP settings to re-apply */ cs35l41_test_key_unlock(cs35l41->dev, cs35l41->regmap); ret = regcache_sync(cs35l41->regmap); @@ -876,6 +941,8 @@ static int cs35l41_runtime_resume(struct device *dev) if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST) cs35l41_init_boost(cs35l41->dev, cs35l41->regmap, &cs35l41->hw_cfg); + dev_dbg(cs35l41->dev, "CS35L41 Resumed (%x), Revision: %02X\n", regid, reg_revid); + err: mutex_unlock(&cs35l41->fw_mutex); @@ -1504,7 +1571,7 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int irq, struct regmap *regmap) { - unsigned int int_sts, regid, reg_revid, mtl_revid, chipid, int_status; + unsigned int regid, reg_revid; struct cs35l41_hda *cs35l41; int ret; @@ -1545,41 +1612,13 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i usleep_range(2000, 2100); - ret = regmap_read_poll_timeout(cs35l41->regmap, CS35L41_IRQ1_STATUS4, int_status, - int_status & CS35L41_OTP_BOOT_DONE, 1000, 100000); - if (ret) { - dev_err(cs35l41->dev, "Failed waiting for OTP_BOOT_DONE: %d\n", ret); - goto err; - } - - ret = regmap_read(cs35l41->regmap, CS35L41_IRQ1_STATUS3, &int_sts); - if (ret || (int_sts & CS35L41_OTP_BOOT_ERR)) { - dev_err(cs35l41->dev, "OTP Boot status %x error: %d\n", - int_sts & CS35L41_OTP_BOOT_ERR, ret); - ret = -EIO; - goto err; - } - - ret = regmap_read(cs35l41->regmap, CS35L41_DEVID, ®id); - if (ret) { - dev_err(cs35l41->dev, "Get Device ID failed: %d\n", ret); - goto err; - } - - ret = regmap_read(cs35l41->regmap, CS35L41_REVID, ®_revid); - if (ret) { - dev_err(cs35l41->dev, "Get Revision ID failed: %d\n", ret); + ret = cs35l41_wait_boot_done(cs35l41); + if (ret) goto err; - } - - mtl_revid = reg_revid & CS35L41_MTLREVID_MASK; - chipid = (mtl_revid % 2) ? CS35L41R_CHIP_ID : CS35L41_CHIP_ID; - if (regid != chipid) { - dev_err(cs35l41->dev, "CS35L41 Device ID (%X). Expected ID %X\n", regid, chipid); - ret = -ENODEV; + ret = cs35l41_verify_id(cs35l41, ®id, ®_revid); + if (ret) goto err; - } ret = cs35l41_test_key_unlock(cs35l41->dev, cs35l41->regmap); if (ret)