From: Stefan Binding <sbinding@opensource.cirrus.com>
To: Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.com>,
"Mark Brown" <broonie@kernel.org>
Cc: <alsa-devel@alsa-project.org>, <linux-kernel@vger.kernel.org>,
<linux-sound@vger.kernel.org>, <patches@opensource.cirrus.com>,
"Stefan Binding" <sbinding@opensource.cirrus.com>
Subject: [PATCH v1 4/8] ALSA: hda: cs35l41: Run boot process during resume callbacks
Date: Thu, 26 Oct 2023 16:05:54 +0100 [thread overview]
Message-ID: <20231026150558.2105827-5-sbinding@opensource.cirrus.com> (raw)
In-Reply-To: <20231026150558.2105827-1-sbinding@opensource.cirrus.com>
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 <sbinding@opensource.cirrus.com>
---
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 1ac721085fb5..e787788c1be2 100644
--- a/sound/pci/hda/cs35l41_hda.c
+++ b/sound/pci/hda/cs35l41_hda.c
@@ -730,6 +730,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;
@@ -827,6 +855,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);
@@ -847,6 +899,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);
@@ -908,6 +968,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");
@@ -929,6 +990,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);
@@ -941,6 +1006,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);
@@ -1660,7 +1727,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;
@@ -1701,41 +1768,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_probe(cs35l41->dev, ret, "Failed waiting for OTP_BOOT_DONE\n");
- goto err;
- }
-
- ret = regmap_read(cs35l41->regmap, CS35L41_IRQ1_STATUS3, &int_sts);
- if (ret || (int_sts & CS35L41_OTP_BOOT_ERR)) {
- dev_err_probe(cs35l41->dev, ret, "OTP Boot status %x error\n",
- int_sts & CS35L41_OTP_BOOT_ERR);
- ret = -EIO;
- goto err;
- }
-
- ret = regmap_read(cs35l41->regmap, CS35L41_DEVID, ®id);
- if (ret) {
- dev_err_probe(cs35l41->dev, ret, "Get Device ID failed\n");
- goto err;
- }
-
- ret = regmap_read(cs35l41->regmap, CS35L41_REVID, ®_revid);
- if (ret) {
- dev_err_probe(cs35l41->dev, ret, "Get Revision ID failed\n");
+ 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)
--
2.34.1
next prev parent reply other threads:[~2023-10-26 15:07 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-10-26 15:05 [PATCH v1 0/8] System Suspend fixes and improvements for CS35L41 HDA Stefan Binding
2023-10-26 15:05 ` [PATCH v1 1/8] ALSA: hda: cs35l41: Use reset label to get GPIO for HP Zbook Fury 17 G9 Stefan Binding
2023-10-26 15:05 ` [PATCH v1 2/8] ALSA: hda: cs35l41: Assert reset before system suspend Stefan Binding
2023-10-26 15:05 ` [PATCH v1 3/8] ALSA: hda: cs35l41: Assert Reset prior to de-asserting in probe and system resume Stefan Binding
2023-10-26 15:05 ` Stefan Binding [this message]
2023-10-26 15:05 ` [PATCH v1 5/8] ALSA: hda: cs35l41: Force a software reset after hardware reset Stefan Binding
2023-10-26 15:05 ` [PATCH v1 6/8] ALSA: hda: cs35l41: Do not unload firmware before reset in system suspend Stefan Binding
2023-10-26 15:05 ` [PATCH v1 7/8] ALSA: hda: cs35l41: Check CSPL state after loading firmware Stefan Binding
2023-10-26 15:05 ` [PATCH v1 8/8] ASoC: cs35l41: Detect CSPL errors when sending CSPL commands Stefan Binding
2023-10-26 15:09 ` Mark Brown
2023-10-26 16:02 ` [PATCH v1 0/8] System Suspend fixes and improvements for CS35L41 HDA Takashi Iwai
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20231026150558.2105827-5-sbinding@opensource.cirrus.com \
--to=sbinding@opensource.cirrus.com \
--cc=alsa-devel@alsa-project.org \
--cc=broonie@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-sound@vger.kernel.org \
--cc=patches@opensource.cirrus.com \
--cc=perex@perex.cz \
--cc=tiwai@suse.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox