[PATCH v3 19/27] ALSA: hda/cs8409: Support multiple sub_codecs for Suspend/Resume/Unsol events

From: Vitaly Rodionov
Date: Fri Jul 30 2021 - 11:20:31 EST


From: Stefan Binding <sbinding@xxxxxxxxxxxxxxxxxxxxx>

Signed-off-by: Stefan Binding <sbinding@xxxxxxxxxxxxxxxxxxxxx>
Signed-off-by: Vitaly Rodionov <vitalyr@xxxxxxxxxxxxxxxxxxxxx>
---

Changes in v2:
- No changes

Changes in v3:
- No changes

sound/pci/hda/patch_cs8409.c | 41 ++++++++++++++++++++++++------------
1 file changed, 28 insertions(+), 13 deletions(-)

diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c
index 4b4f4dc54617..8b048ff12eb7 100644
--- a/sound/pci/hda/patch_cs8409.c
+++ b/sound/pci/hda/patch_cs8409.c
@@ -375,16 +375,21 @@ static int cs8409_build_controls(struct hda_codec *codec)
return 0;
}

-/* Enable/Disable Unsolicited Response for gpio(s) 3,4 */
+/* Enable/Disable Unsolicited Response */
static void cs8409_enable_ur(struct hda_codec *codec, int flag)
{
- /* GPIO4 INT# and GPIO3 WAKE# */
+ struct cs8409_spec *spec = codec->spec;
+ unsigned int ur_gpios = 0;
+ int i;
+
+ for (i = 0; i < spec->num_scodecs; i++)
+ ur_gpios |= spec->scodecs[i]->irq_mask;
+
snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK,
- flag ? CS8409_CS42L42_INT : 0);
+ flag ? ur_gpios : 0);

snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_UNSOLICITED_ENABLE,
flag ? AC_UNSOL_ENABLED : 0);
-
}

static void cs8409_fix_caps(struct hda_codec *codec, unsigned int nid)
@@ -616,6 +621,8 @@ static int cs42l42_jack_unsol_event(struct sub_codec *cs42l42)

static void cs42l42_resume(struct sub_codec *cs42l42)
{
+ struct hda_codec *codec = cs42l42->codec;
+ unsigned int gpio_data;
struct cs8409_i2c_param irq_regs[] = {
{ 0x1308, 0x00 },
{ 0x1309, 0x00 },
@@ -623,6 +630,12 @@ static void cs42l42_resume(struct sub_codec *cs42l42)
{ 0x130F, 0x00 },
};

+ /* Bring CS42L42 out of Reset */
+ gpio_data = snd_hda_codec_read(codec, CS8409_PIN_AFG, 0, AC_VERB_GET_GPIO_DATA, 0);
+ gpio_data |= cs42l42->reset_gpio;
+ snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_DATA, gpio_data);
+ usleep_range(10000, 15000);
+
cs42l42->suspended = 0;

/* Initialize CS42L42 companion codec */
@@ -648,10 +661,18 @@ static void cs42l42_resume(struct sub_codec *cs42l42)
#ifdef CONFIG_PM
static void cs42l42_suspend(struct sub_codec *cs42l42)
{
+ struct hda_codec *codec = cs42l42->codec;
+ unsigned int gpio_data;
+
/* Power down CS42L42 ASP/EQ/MIX/HP */
cs8409_i2c_write(cs42l42, 0x1101, 0xfe);
cs42l42->suspended = 1;
cs42l42->last_page = 0;
+
+ /* Put CS42L42 into Reset */
+ gpio_data = snd_hda_codec_read(codec, CS8409_PIN_AFG, 0, AC_VERB_GET_GPIO_DATA, 0);
+ gpio_data &= ~cs42l42->reset_gpio;
+ snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_DATA, gpio_data);
}
#endif

@@ -710,13 +731,12 @@ static void cs8409_cs42l42_jack_unsol_event(struct hda_codec *codec, unsigned in
static int cs8409_cs42l42_suspend(struct hda_codec *codec)
{
struct cs8409_spec *spec = codec->spec;
+ int i;

cs8409_enable_ur(codec, 0);

- cs42l42_suspend(spec->scodecs[CS8409_CODEC0]);
-
- /* Assert CS42L42 RTS# line */
- snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_DATA, 0);
+ for (i = 0; i < spec->num_scodecs; i++)
+ cs42l42_suspend(spec->scodecs[i]);

snd_hda_shutup_pins(codec);

@@ -755,11 +775,6 @@ static void cs8409_cs42l42_hw_init(struct hda_codec *codec)
if (codec->fixup_id == CS8409_WARLOCK || codec->fixup_id == CS8409_CYBORG)
cs8409_vendor_coef_set(codec, 0x09, 0x0003);

- /* Release RTS# line */
- snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_DATA, CS8409_CS42L42_RESET);
- /* wait ~10ms */
- usleep_range(10000, 15000);
-
cs42l42_resume(cs42l42);

/* Enable Unsolicited Response */
--
2.25.1