From patchwork Tue Aug 1 08:36:40 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kai-Heng Feng X-Patchwork-Id: 1815421 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=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=canonical.com header.i=@canonical.com header.a=rsa-sha256 header.s=20210705 header.b=jIAWYwcj; dkim-atps=neutral Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (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 4RFT5S2cCzz1yZl for ; Tue, 1 Aug 2023 18:38:04 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1qQkt9-0002cg-J8; Tue, 01 Aug 2023 08:37:55 +0000 Received: from smtp-relay-canonical-0.internal ([10.131.114.83] helo=smtp-relay-canonical-0.canonical.com) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1qQkt5-0002VK-Od for kernel-team@lists.ubuntu.com; Tue, 01 Aug 2023 08:37:51 +0000 Received: from localhost.localdomain (unknown [10.101.196.174]) (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-canonical-0.canonical.com (Postfix) with ESMTPSA id E3D653F7B7 for ; Tue, 1 Aug 2023 08:37:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1690879069; bh=Grh4/iWrtG/QeOZLy8NLrGkMO4CK2XV9lidklUyzh8s=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=jIAWYwcjZ1hQ6zK2yIYLDkVshTpJ4fMAU4FRmPKo3YhfpSy3sZ6vnNlapgrcmD91B Nx9n65cnWvyUbZmH+p1AUHQgj7d6sOqTgxPcpBk0MaXmQeefN2cGeoKcMN/pb/W5yT ORznzvik6qVatzvTkW5h4+cJchfQvQFNbVEuVOiyIXybXlfHjakU9vc0+M8jrfB+3Y v28O5XaUwsHmchEA3OhOfFFlJgV31R7j+8gaFoif2lQWgzzF0PuDGT45K+d1a8nqlU 18xtftjlNvgjW7vm9cm0TfmmIGIDd7FElS5gsOeYcfeV1l1T+nt3oqvdpiLoninuS2 lkYPeXeqt5Wmg== From: Kai-Heng Feng To: kernel-team@lists.ubuntu.com Subject: [L/Unstable] [PATCH 07/16] ALSA: cs35l41: Poll for Power Up/Down rather than waiting a fixed delay Date: Tue, 1 Aug 2023 16:36:40 +0800 Message-Id: <20230801083649.3602806-8-kai.heng.feng@canonical.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230801083649.3602806-1-kai.heng.feng@canonical.com> References: <20230801083649.3602806-1-kai.heng.feng@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/2029199 To ensure the chip has correctly powered up or down before continuing, the driver will now poll a register, rather than wait a fixed delay. Acked-by: Mark Brown Signed-off-by: Stefan Binding Link: https://lore.kernel.org/r/20230721151816.2080453-3-sbinding@opensource.cirrus.com Signed-off-by: Takashi Iwai (cherry picked from commit f8264c7592088727629e14f396f95ad643847740 linux-next) Signed-off-by: Kai-Heng Feng --- sound/soc/codecs/cs35l41-lib.c | 48 +++++++++++++++++++++++++++++++--- sound/soc/codecs/cs35l41.c | 10 ------- 2 files changed, 44 insertions(+), 14 deletions(-) diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c index bd44a2106143..7405390ee35e 100644 --- a/sound/soc/codecs/cs35l41-lib.c +++ b/sound/soc/codecs/cs35l41-lib.c @@ -1196,7 +1196,8 @@ int cs35l41_global_enable(struct device *dev, struct regmap *regmap, enum cs35l4 int enable, struct completion *pll_lock, bool firmware_running) { int ret; - unsigned int gpio1_func, pad_control, pwr_ctrl1, pwr_ctrl3, int_status; + unsigned int gpio1_func, pad_control, pwr_ctrl1, pwr_ctrl3, int_status, pup_pdn_mask; + unsigned int pwr_ctl1_val; struct reg_sequence cs35l41_mdsync_down_seq[] = { {CS35L41_PWR_CTRL3, 0}, {CS35L41_GPIO_PAD_CONTROL, 0}, @@ -1208,6 +1209,12 @@ int cs35l41_global_enable(struct device *dev, struct regmap *regmap, enum cs35l4 {CS35L41_PWR_CTRL1, 0x00000001, 3000}, }; + pup_pdn_mask = enable ? CS35L41_PUP_DONE_MASK : CS35L41_PDN_DONE_MASK; + + ret = regmap_read(regmap, CS35L41_PWR_CTRL1, &pwr_ctl1_val); + if (ret) + return ret; + if ((pwr_ctl1_val & CS35L41_GLOBAL_EN_MASK) && enable) { dev_dbg(dev, "Cannot set Global Enable - already set.\n"); return 0; @@ -1252,6 +1259,15 @@ int cs35l41_global_enable(struct device *dev, struct regmap *regmap, enum cs35l4 ret = regmap_multi_reg_write(regmap, cs35l41_mdsync_up_seq, ARRAY_SIZE(cs35l41_mdsync_up_seq)); } + + ret = regmap_read_poll_timeout(regmap, CS35L41_IRQ1_STATUS1, + int_status, int_status & pup_pdn_mask, + 1000, 100000); + if (ret) + dev_err(dev, "Enable(%d) failed: %d\n", enable, ret); + + // Clear PUP/PDN status + regmap_write(regmap, CS35L41_IRQ1_STATUS1, pup_pdn_mask); break; case CS35L41_INT_BOOST: ret = regmap_update_bits(regmap, CS35L41_PWR_CTRL1, CS35L41_GLOBAL_EN_MASK, @@ -1260,7 +1276,15 @@ int cs35l41_global_enable(struct device *dev, struct regmap *regmap, enum cs35l4 dev_err(dev, "CS35L41_PWR_CTRL1 set failed: %d\n", ret); return ret; } - usleep_range(3000, 3100); + + ret = regmap_read_poll_timeout(regmap, CS35L41_IRQ1_STATUS1, + int_status, int_status & pup_pdn_mask, + 1000, 100000); + if (ret) + dev_err(dev, "Enable(%d) failed: %d\n", enable, ret); + + /* Clear PUP/PDN status */ + regmap_write(regmap, CS35L41_IRQ1_STATUS1, pup_pdn_mask); break; case CS35L41_EXT_BOOST: case CS35L41_EXT_BOOST_NO_VSPK_SWITCH: @@ -1271,7 +1295,15 @@ int cs35l41_global_enable(struct device *dev, struct regmap *regmap, enum cs35l4 if (ret) return ret; - usleep_range(3000, 3100); + ret = regmap_read_poll_timeout(regmap, CS35L41_IRQ1_STATUS1, int_status, + int_status & CS35L41_PUP_DONE_MASK, 1000, 100000); + if (ret) { + dev_err(dev, "Failed waiting for CS35L41_PUP_DONE_MASK: %d\n", ret); + /* Lock the test key, it was unlocked during the multi_reg_write */ + cs35l41_test_key_lock(dev, regmap); + return ret; + } + regmap_write(regmap, CS35L41_IRQ1_STATUS1, CS35L41_PUP_DONE_MASK); if (firmware_running) ret = cs35l41_set_cspl_mbox_cmd(dev, regmap, @@ -1292,7 +1324,15 @@ int cs35l41_global_enable(struct device *dev, struct regmap *regmap, enum cs35l4 return ret; } - usleep_range(3000, 3100); + ret = regmap_read_poll_timeout(regmap, CS35L41_IRQ1_STATUS1, int_status, + int_status & CS35L41_PDN_DONE_MASK, 1000, 100000); + if (ret) { + dev_err(dev, "Failed waiting for CS35L41_PDN_DONE_MASK: %d\n", ret); + /* Lock the test key, it was unlocked during the multi_reg_write */ + cs35l41_test_key_lock(dev, regmap); + return ret; + } + regmap_write(regmap, CS35L41_IRQ1_STATUS1, CS35L41_PDN_DONE_MASK); /* Test Key is locked here */ ret = regmap_multi_reg_write(regmap, cs35l41_active_to_safe_end, diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c index ebe7adec9ba4..e8f36c95a778 100644 --- a/sound/soc/codecs/cs35l41.c +++ b/sound/soc/codecs/cs35l41.c @@ -490,7 +490,6 @@ static int cs35l41_main_amp_event(struct snd_soc_dapm_widget *w, { struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(component); - unsigned int val; int ret = 0; switch (event) { @@ -506,15 +505,6 @@ static int cs35l41_main_amp_event(struct snd_soc_dapm_widget *w, ret = cs35l41_global_enable(cs35l41->dev, cs35l41->regmap, cs35l41->hw_cfg.bst_type, 0, &cs35l41->pll_lock, cs35l41->dsp.cs_dsp.running); - ret = regmap_read_poll_timeout(cs35l41->regmap, CS35L41_IRQ1_STATUS1, - val, val & CS35L41_PDN_DONE_MASK, - 1000, 100000); - if (ret) - dev_warn(cs35l41->dev, "PDN failed: %d\n", ret); - - regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, - CS35L41_PDN_DONE_MASK); - regmap_multi_reg_write_bypassed(cs35l41->regmap, cs35l41_pdn_patch, ARRAY_SIZE(cs35l41_pdn_patch));