2021-08-12 20:24:11

by Vitaly Rodionov

[permalink] [raw]
Subject: [PATCH 1/2] ALSA: hda/cs8409: Prevent pops and clicks during suspend

From: Stefan Binding <[email protected]>

Some of the register values set for type detection cause pops during suspend,
ensure these are cleaned up after type detection completes, as well
ensuring that these are cleared when we suspend.

Signed-off-by: Stefan Binding <[email protected]>
Signed-off-by: Vitaly Rodionov <[email protected]>
---
sound/pci/hda/patch_cs8409.c | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c
index 272497b6cfcb..9db16b6292f4 100644
--- a/sound/pci/hda/patch_cs8409.c
+++ b/sound/pci/hda/patch_cs8409.c
@@ -708,6 +708,10 @@ static int cs42l42_jack_unsol_event(struct sub_codec *cs42l42)
cs42l42->mic_jack_in = 1;
}
}
+ /* Configure the HSDET mode. */
+ cs8409_i2c_write(cs42l42, 0x1120, 0x80);
+ /* Enable the HPOUT ground clamp and configure the HP pull-down */
+ cs8409_i2c_write(cs42l42, 0x1F06, 0x02);
/* Re-Enable Tip Sense Interrupt */
cs8409_i2c_write(cs42l42, 0x1320, 0xF3);
} else {
@@ -756,6 +760,8 @@ static void cs42l42_suspend(struct sub_codec *cs42l42)
unsigned int gpio_data;
int reg_cdc_status = 0;
const struct cs8409_i2c_param cs42l42_pwr_down_seq[] = {
+ { 0x1F06, 0x02 },
+ { 0x1129, 0x00 },
{ 0x2301, 0x3F },
{ 0x2302, 0x3F },
{ 0x2303, 0x3F },
--
2.25.1


2021-08-12 21:39:00

by Vitaly Rodionov

[permalink] [raw]
Subject: [PATCH 2/2] ALSA: hda/cs8409: Prevent pops and clicks during reboot

From: Stefan Binding <[email protected]>

During reboot, when the CS42L42 powers down, pops and clicks
may occur due to the codec not being shutdown gracefully.
This can be fixed by going through the suspend sequence,
which shuts down the codec cleanly inside the reboot_notify
hook, which is called on reboot.

Signed-off-by: Stefan Binding <[email protected]>
Signed-off-by: Vitaly Rodionov <[email protected]>
---
sound/pci/hda/patch_cs8409.c | 56 ++++++++++++++++++++----------------
1 file changed, 32 insertions(+), 24 deletions(-)

diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c
index 9db16b6292f4..f51fc4a1545a 100644
--- a/sound/pci/hda/patch_cs8409.c
+++ b/sound/pci/hda/patch_cs8409.c
@@ -753,7 +753,6 @@ static void cs42l42_resume(struct sub_codec *cs42l42)
cs42l42_enable_jack_detect(cs42l42);
}

-#ifdef CONFIG_PM
static void cs42l42_suspend(struct sub_codec *cs42l42)
{
struct hda_codec *codec = cs42l42->codec;
@@ -773,6 +772,9 @@ static void cs42l42_suspend(struct sub_codec *cs42l42)
{ 0x1101, 0xFF },
};

+ if (cs42l42->suspended)
+ return;
+
cs8409_i2c_bulk_write(cs42l42, cs42l42_pwr_down_seq, ARRAY_SIZE(cs42l42_pwr_down_seq));

if (read_poll_timeout(cs8409_i2c_read, reg_cdc_status,
@@ -790,7 +792,6 @@ static void cs42l42_suspend(struct sub_codec *cs42l42)
gpio_data &= ~cs42l42->reset_gpio;
snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_DATA, gpio_data);
}
-#endif

static void cs8409_free(struct hda_codec *codec)
{
@@ -803,6 +804,33 @@ static void cs8409_free(struct hda_codec *codec)
snd_hda_gen_free(codec);
}

+/* Manage PDREF, when transition to D3hot */
+static int cs8409_cs42l42_suspend(struct hda_codec *codec)
+{
+ struct cs8409_spec *spec = codec->spec;
+ int i;
+
+ cs8409_enable_ur(codec, 0);
+
+ for (i = 0; i < spec->num_scodecs; i++)
+ cs42l42_suspend(spec->scodecs[i]);
+
+ /* Cancel i2c clock disable timer, and disable clock if left enabled */
+ cancel_delayed_work_sync(&spec->i2c_clk_work);
+ cs8409_disable_i2c_clock(codec);
+
+ snd_hda_shutup_pins(codec);
+
+ return 0;
+}
+
+static void cs8409_reboot_notify(struct hda_codec *codec)
+{
+ cs8409_cs42l42_suspend(codec);
+ snd_hda_gen_reboot_notify(codec);
+ codec->patch_ops.free(codec);
+}
+
/******************************************************************************
* BULLSEYE / WARLOCK / CYBORG Specific Functions
* CS8409/CS42L42
@@ -845,28 +873,6 @@ static void cs8409_cs42l42_jack_unsol_event(struct hda_codec *codec, unsigned in
}
}

-#ifdef CONFIG_PM
-/* Manage PDREF, when transition to D3hot */
-static int cs8409_cs42l42_suspend(struct hda_codec *codec)
-{
- struct cs8409_spec *spec = codec->spec;
- int i;
-
- cs8409_enable_ur(codec, 0);
-
- for (i = 0; i < spec->num_scodecs; i++)
- cs42l42_suspend(spec->scodecs[i]);
-
- /* Cancel i2c clock disable timer, and disable clock if left enabled */
- cancel_delayed_work_sync(&spec->i2c_clk_work);
- cs8409_disable_i2c_clock(codec);
-
- snd_hda_shutup_pins(codec);
-
- return 0;
-}
-#endif
-
/* Vendor specific HW configuration
* PLL, ASP, I2C, SPI, GPIOs, DMIC etc...
*/
@@ -910,6 +916,7 @@ static const struct hda_codec_ops cs8409_cs42l42_patch_ops = {
.init = cs8409_init,
.free = cs8409_free,
.unsol_event = cs8409_cs42l42_jack_unsol_event,
+ .reboot_notify = cs8409_reboot_notify,
#ifdef CONFIG_PM
.suspend = cs8409_cs42l42_suspend,
#endif
@@ -1121,6 +1128,7 @@ static const struct hda_codec_ops cs8409_dolphin_patch_ops = {
.init = cs8409_init,
.free = cs8409_free,
.unsol_event = dolphin_jack_unsol_event,
+ .reboot_notify = cs8409_reboot_notify,
#ifdef CONFIG_PM
.suspend = cs8409_cs42l42_suspend,
#endif
--
2.25.1

2021-08-13 06:37:59

by Takashi Iwai

[permalink] [raw]
Subject: Re: [PATCH 1/2] ALSA: hda/cs8409: Prevent pops and clicks during suspend

On Thu, 12 Aug 2021 20:34:32 +0200,
Vitaly Rodionov wrote:
>
> From: Stefan Binding <[email protected]>
>
> Some of the register values set for type detection cause pops during suspend,
> ensure these are cleaned up after type detection completes, as well
> ensuring that these are cleared when we suspend.
>
> Signed-off-by: Stefan Binding <[email protected]>
> Signed-off-by: Vitaly Rodionov <[email protected]>

Thanks, this one is applied now.


Takashi

2021-08-13 06:39:29

by Takashi Iwai

[permalink] [raw]
Subject: Re: [PATCH 2/2] ALSA: hda/cs8409: Prevent pops and clicks during reboot

On Thu, 12 Aug 2021 20:34:33 +0200,
Vitaly Rodionov wrote:
>
> From: Stefan Binding <[email protected]>
>
> During reboot, when the CS42L42 powers down, pops and clicks
> may occur due to the codec not being shutdown gracefully.
> This can be fixed by going through the suspend sequence,
> which shuts down the codec cleanly inside the reboot_notify
> hook, which is called on reboot.
>
> Signed-off-by: Stefan Binding <[email protected]>
> Signed-off-by: Vitaly Rodionov <[email protected]>

I hold this one for now, as there is a fix series that deprecates the
reboot_notify callback of HD-audio by forcibly doing runtime-suspend
at shutdown. Please check the three patches in
https://bugzilla.kernel.org/show_bug.cgi?id=214045

I'm going to submit those soon in anyway.


thanks,

Takashi

2021-08-14 06:43:05

by Takashi Iwai

[permalink] [raw]
Subject: Re: [PATCH 2/2] ALSA: hda/cs8409: Prevent pops and clicks during reboot

On Fri, 13 Aug 2021 08:10:47 +0200,
Takashi Iwai wrote:
>
> On Thu, 12 Aug 2021 20:34:33 +0200,
> Vitaly Rodionov wrote:
> >
> > From: Stefan Binding <[email protected]>
> >
> > During reboot, when the CS42L42 powers down, pops and clicks
> > may occur due to the codec not being shutdown gracefully.
> > This can be fixed by going through the suspend sequence,
> > which shuts down the codec cleanly inside the reboot_notify
> > hook, which is called on reboot.
> >
> > Signed-off-by: Stefan Binding <[email protected]>
> > Signed-off-by: Vitaly Rodionov <[email protected]>
>
> I hold this one for now, as there is a fix series that deprecates the
> reboot_notify callback of HD-audio by forcibly doing runtime-suspend
> at shutdown. Please check the three patches in
> https://bugzilla.kernel.org/show_bug.cgi?id=214045
>
> I'm going to submit those soon in anyway.

The removal of reboot_notifier landed in my for-next branch now.
Please rebase and adapt the changes appropriately. In short, the
runtime suspend is applied at the shutdown, so the workaround is
needed only for suspend.


thanks,

Takashi

2021-08-17 12:02:02

by Vitaly Rodionov

[permalink] [raw]
Subject: Re: [PATCH 2/2] ALSA: hda/cs8409: Prevent pops and clicks during reboot

On 14/08/2021 7:41 am, Takashi Iwai wrote:
> On Fri, 13 Aug 2021 08:10:47 +0200,
> Takashi Iwai wrote:
>> On Thu, 12 Aug 2021 20:34:33 +0200,
>> Vitaly Rodionov wrote:
>>> From: Stefan Binding <[email protected]>
>>>
>>> During reboot, when the CS42L42 powers down, pops and clicks
>>> may occur due to the codec not being shutdown gracefully.
>>> This can be fixed by going through the suspend sequence,
>>> which shuts down the codec cleanly inside the reboot_notify
>>> hook, which is called on reboot.
>>>
>>> Signed-off-by: Stefan Binding <[email protected]>
>>> Signed-off-by: Vitaly Rodionov <[email protected]>
>> I hold this one for now, as there is a fix series that deprecates the
>> reboot_notify callback of HD-audio by forcibly doing runtime-suspend
>> at shutdown. Please check the three patches in
>> https://bugzilla.kernel.org/show_bug.cgi?id=214045
>>
>> I'm going to submit those soon in anyway.

Hi Takashi,

Thanks for letting us know. We have tested against for-next branch and
we have an issue.

Loud pops on reboot. It looks like suspend have never been called on
reboot or shutdown for us.

> The removal of reboot_notifier landed in my for-next branch now.
> Please rebase and adapt the changes appropriately. In short, the
> runtime suspend is applied at the shutdown, so the workaround is
> needed only for suspend.
>
>
> thanks,
>
> Takashi


2021-08-17 12:17:55

by Takashi Iwai

[permalink] [raw]
Subject: Re: [PATCH 2/2] ALSA: hda/cs8409: Prevent pops and clicks during reboot

On Tue, 17 Aug 2021 13:28:21 +0200,
Vitaly Rodionov wrote:
>
> On 14/08/2021 7:41 am, Takashi Iwai wrote:
> > On Fri, 13 Aug 2021 08:10:47 +0200,
> > Takashi Iwai wrote:
> >> On Thu, 12 Aug 2021 20:34:33 +0200,
> >> Vitaly Rodionov wrote:
> >>> From: Stefan Binding <[email protected]>
> >>>
> >>> During reboot, when the CS42L42 powers down, pops and clicks
> >>> may occur due to the codec not being shutdown gracefully.
> >>> This can be fixed by going through the suspend sequence,
> >>> which shuts down the codec cleanly inside the reboot_notify
> >>> hook, which is called on reboot.
> >>>
> >>> Signed-off-by: Stefan Binding <[email protected]>
> >>> Signed-off-by: Vitaly Rodionov <[email protected]>
> >> I hold this one for now, as there is a fix series that deprecates the
> >> reboot_notify callback of HD-audio by forcibly doing runtime-suspend
> >> at shutdown. Please check the three patches in
> >> https://bugzilla.kernel.org/show_bug.cgi?id=214045
> >>
> >> I'm going to submit those soon in anyway.
>
> Hi Takashi,
>
> Thanks for letting us know. We have tested against for-next branch and
> we have an issue.
>
> Loud pops on reboot. It looks like suspend have never been called on
> reboot or shutdown for us.

OK, we need to track down the cause.

Does the noise persist if the codec has been runtime-suspended
beforehand? You can check the status in sysfs.


thanks,

Takashi

2021-08-26 06:06:05

by Takashi Iwai

[permalink] [raw]
Subject: Re: [PATCH 2/2] ALSA: hda/cs8409: Prevent pops and clicks during reboot

On Wed, 25 Aug 2021 20:04:05 +0200,
Vitaly Rodionov wrote:
> Actually when codec is suspended and we do reboot from UI, then sometimes we
> see suspend() calls in kernel log and no pops, but sometimes
>
> we still have no suspend() on reboot and we hear pops. But when we do reboot
> from command line: > sudo reboot  then we always have pops and no suspend()
> called.
>
> Then we have added extra logging and we can see that on reboot codec somehow
> getting resume() call and we run jack detect on resume that causing pops.

Hm, it's interesting who triggers the runtime resume.

> We were thinking about possible solution for that and we would propose some
> changes in generic code hda_bind.c:
>
> static void hda_codec_driver_shutdown(struct device *dev) { +   if (codec->
> patch_ops.suspend) +      codec->patch_ops.suspend(codec);   
> snd_hda_codec_shutdown(dev_to_hda_codec(dev)); +  hda_codec_driver_remove
> (dev_to_hda_codec(dev)); }

Sorry, it's no-no. The suspend can't be called unconditionally, and
the driver unbind must not be called in the callback itself.

Does the patch below work instead?


thanks,

Takashi

--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -2356,8 +2356,11 @@ static void azx_shutdown(struct pci_dev *pci)
if (!card)
return;
chip = card->private_data;
- if (chip && chip->running)
+ if (chip && chip->running) {
+ chip->bus.shutdown = 1;
+ cancel_work_sync(&bus->unsol_work);
azx_shutdown_chip(chip);
+ }
}

/* PCI IDs */

2021-08-26 10:51:36

by Takashi Iwai

[permalink] [raw]
Subject: Re: [PATCH 2/2] ALSA: hda/cs8409: Prevent pops and clicks during reboot

On Thu, 26 Aug 2021 08:03:45 +0200,
Takashi Iwai wrote:
>
> On Wed, 25 Aug 2021 20:04:05 +0200,
> Vitaly Rodionov wrote:
> > Actually when codec is suspended and we do reboot from UI, then sometimes we
> > see suspend() calls in kernel log and no pops, but sometimes
> >
> > we still have no suspend() on reboot and we hear pops. But when we do reboot
> > from command line: > sudo reboot  then we always have pops and no suspend()
> > called.
> >
> > Then we have added extra logging and we can see that on reboot codec somehow
> > getting resume() call and we run jack detect on resume that causing pops.
>
> Hm, it's interesting who triggers the runtime resume.
>
> > We were thinking about possible solution for that and we would propose some
> > changes in generic code hda_bind.c:
> >
> > static void hda_codec_driver_shutdown(struct device *dev) { +   if (codec->
> > patch_ops.suspend) +      codec->patch_ops.suspend(codec);   
> > snd_hda_codec_shutdown(dev_to_hda_codec(dev)); +  hda_codec_driver_remove
> > (dev_to_hda_codec(dev)); }
>
> Sorry, it's no-no. The suspend can't be called unconditionally, and
> the driver unbind must not be called in the callback itself.
>
> Does the patch below work instead?

Sorry there was a typo. A bit more revised patch is below.


Takashi

--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -1383,14 +1383,17 @@ static void azx_free(struct azx *chip)
hda->freed = 1;
}

-static int azx_dev_disconnect(struct snd_device *device)
+static void __azx_disconnect(struct azx *chip)
{
- struct azx *chip = device->device_data;
struct hdac_bus *bus = azx_bus(chip);

chip->bus.shutdown = 1;
cancel_work_sync(&bus->unsol_work);
+}

+static int azx_dev_disconnect(struct snd_device *device)
+{
+ __azx_disconnect(device->device_data);
return 0;
}

@@ -2356,8 +2359,10 @@ static void azx_shutdown(struct pci_dev *pci)
if (!card)
return;
chip = card->private_data;
- if (chip && chip->running)
+ if (chip && chip->running) {
+ __azx_disconnect(chip);
azx_shutdown_chip(chip);
+ }
}

/* PCI IDs */

2021-08-26 10:57:29

by Vitaly Rodionov

[permalink] [raw]
Subject: Re: [PATCH 2/2] ALSA: hda/cs8409: Prevent pops and clicks during reboot

On 26/08/2021 11:49 am, Takashi Iwai wrote:
> On Thu, 26 Aug 2021 08:03:45 +0200,
> Takashi Iwai wrote:
>> On Wed, 25 Aug 2021 20:04:05 +0200,
>> Vitaly Rodionov wrote:
>>> Actually when codec is suspended and we do reboot from UI, then sometimes we
>>> see suspend() calls in kernel log and no pops, but sometimes
>>>
>>> we still have no suspend() on reboot and we hear pops. But when we do reboot
>>> from command line: > sudo reboot  then we always have pops and no suspend()
>>> called.
>>>
>>> Then we have added extra logging and we can see that on reboot codec somehow
>>> getting resume() call and we run jack detect on resume that causing pops.
>> Hm, it's interesting who triggers the runtime resume.
>>
>>> We were thinking about possible solution for that and we would propose some
>>> changes in generic code hda_bind.c:
>>>
>>> static void hda_codec_driver_shutdown(struct device *dev) { +   if (codec->
>>> patch_ops.suspend) +      codec->patch_ops.suspend(codec);
>>> snd_hda_codec_shutdown(dev_to_hda_codec(dev)); +  hda_codec_driver_remove
>>> (dev_to_hda_codec(dev)); }
>> Sorry, it's no-no. The suspend can't be called unconditionally, and
>> the driver unbind must not be called in the callback itself.
>>
>> Does the patch below work instead?
> Sorry there was a typo. A bit more revised patch is below.
>
>
> Takashi

Hi Takashi,

Thanks a lot for quick response. I have tested previous patch and it did
not fix an issue, as suspend() was not called.

Now I will test new revised patch and let you know ASAP.

I am adding some extra logging, unfortunately on reboot these messages
are missing from kernel log, however I managed to capture reboot screen

and I will attach an image where last messages shown.

Thanks,

Vitaly

>
> --- a/sound/pci/hda/hda_intel.c
> +++ b/sound/pci/hda/hda_intel.c
> @@ -1383,14 +1383,17 @@ static void azx_free(struct azx *chip)
> hda->freed = 1;
> }
>
> -static int azx_dev_disconnect(struct snd_device *device)
> +static void __azx_disconnect(struct azx *chip)
> {
> - struct azx *chip = device->device_data;
> struct hdac_bus *bus = azx_bus(chip);
>
> chip->bus.shutdown = 1;
> cancel_work_sync(&bus->unsol_work);
> +}
>
> +static int azx_dev_disconnect(struct snd_device *device)
> +{
> + __azx_disconnect(device->device_data);
> return 0;
> }
>
> @@ -2356,8 +2359,10 @@ static void azx_shutdown(struct pci_dev *pci)
> if (!card)
> return;
> chip = card->private_data;
> - if (chip && chip->running)
> + if (chip && chip->running) {
> + __azx_disconnect(chip);
> azx_shutdown_chip(chip);
> + }
> }
>
> /* PCI IDs */