Subject: [PATCH] ALSA: Don't cold reset AC97 codecs in some ICH chipsets

Check in a quirk list if it should do cold reset when AC97 power saving
is enabled. Some devices do not resume properly when cold reset,
although power saving works OK.

Signed-off-by: Thadeu Lima de Souza Cascardo <[email protected]>
---
sound/pci/intel8x0.c | 60 ++++++++++++++++++++++++++++++++++++-------------
1 files changed, 44 insertions(+), 16 deletions(-)

diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index 19d3391..69b3ed8 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -2287,23 +2287,23 @@ static void do_ali_reset(struct intel8x0 *chip)
iputdword(chip, ICHREG(ALI_INTERRUPTSR), 0x00000000);
}

-static int snd_intel8x0_ich_chip_init(struct intel8x0 *chip, int probing)
-{
- unsigned long end_time;
- unsigned int cnt, status, nstatus;
-
- /* put logic to right state */
- /* first clear status bits */
- status = ICH_RCS | ICH_MCINT | ICH_POINT | ICH_PIINT;
- if (chip->device_type == DEVICE_NFORCE)
- status |= ICH_NVSPINT;
- cnt = igetdword(chip, ICHREG(GLOB_STA));
- iputdword(chip, ICHREG(GLOB_STA), cnt & status);
+#ifdef CONFIG_SND_AC97_POWER_SAVE
+static struct snd_pci_quirk ich_chip_reset_mode[] = {
+ SND_PCI_QUIRK(0x1014, 0x051f, "Thinkpad R32", 1),
+ { } /* end */
+};

+static int snd_intel8x0_ich_chip_cold_reset(struct intel8x0 *chip)
+{
+ unsigned int cnt;
/* ACLink on, 2 channels */
+
+ if (snd_pci_quirk_lookup(chip->pci, ich_chip_reset_mode))
+ return -EIO;
+
cnt = igetdword(chip, ICHREG(GLOB_CNT));
cnt &= ~(ICH_ACLINK | ICH_PCM_246_MASK);
-#ifdef CONFIG_SND_AC97_POWER_SAVE
+
/* do cold reset - the full ac97 powerdown may leave the controller
* in a warm state but actually it cannot communicate with the codec.
*/
@@ -2312,22 +2312,50 @@ static int snd_intel8x0_ich_chip_init(struct intel8x0 *chip, int probing)
udelay(10);
iputdword(chip, ICHREG(GLOB_CNT), cnt | ICH_AC97COLD);
msleep(1);
+ return 0;
+}
#else
+#define snd_intel8x0_ich_chip_cold_reset(x) 0
+#endif
+
+static int snd_intel8x0_ich_chip_reset(struct intel8x0 *chip)
+{
+ unsigned int cnt;
+ /* ACLink on, 2 channels */
+ cnt = igetdword(chip, ICHREG(GLOB_CNT));
+ cnt &= ~(ICH_ACLINK | ICH_PCM_246_MASK);
/* finish cold or do warm reset */
cnt |= (cnt & ICH_AC97COLD) == 0 ? ICH_AC97COLD : ICH_AC97WARM;
iputdword(chip, ICHREG(GLOB_CNT), cnt);
end_time = (jiffies + (HZ / 4)) + 1;
do {
if ((igetdword(chip, ICHREG(GLOB_CNT)) & ICH_AC97WARM) == 0)
- goto __ok;
+ return 0;
schedule_timeout_uninterruptible(1);
} while (time_after_eq(end_time, jiffies));
snd_printk(KERN_ERR "AC'97 warm reset still in progress? [0x%x]\n",
igetdword(chip, ICHREG(GLOB_CNT)));
return -EIO;
+}
+
+static int snd_intel8x0_ich_chip_init(struct intel8x0 *chip, int probing)
+{
+ unsigned long end_time;
+ unsigned int status, nstatus;
+ int err;
+
+ /* put logic to right state */
+ /* first clear status bits */
+ status = ICH_RCS | ICH_MCINT | ICH_POINT | ICH_PIINT;
+ if (chip->device_type == DEVICE_NFORCE)
+ status |= ICH_NVSPINT;
+ cnt = igetdword(chip, ICHREG(GLOB_STA));
+ iputdword(chip, ICHREG(GLOB_STA), cnt & status);
+
+ if (snd_intel8x0_ich_chip_cold_reset(chip) < 0)
+ if ((err = snd_intel8x0_ich_chip_reset(chip)) < 0)
+ return err;

- __ok:
-#endif
if (probing) {
/* wait for any codec ready status.
* Once it becomes ready it should remain ready
--
1.6.0.6


2009-01-28 12:06:41

by Takashi Iwai

[permalink] [raw]
Subject: Re: [PATCH] ALSA: Don't cold reset AC97 codecs in some ICH chipsets

At Wed, 28 Jan 2009 08:02:36 -0200,
Thadeu Lima de Souza Cascardo wrote:
>
> Check in a quirk list if it should do cold reset when AC97 power saving
> is enabled. Some devices do not resume properly when cold reset,
> although power saving works OK.
>
> Signed-off-by: Thadeu Lima de Souza Cascardo <[email protected]>

Thanks for the patch.
We can go better further with this patch now :)

The logic is basically fine, but just a few comments...

> diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
> index 19d3391..69b3ed8 100644
> --- a/sound/pci/intel8x0.c
> +++ b/sound/pci/intel8x0.c
...
> +static int snd_intel8x0_ich_chip_cold_reset(struct intel8x0 *chip)
> +{
> + unsigned int cnt;
> /* ACLink on, 2 channels */
> +
> + if (snd_pci_quirk_lookup(chip->pci, ich_chip_reset_mode))
> + return -EIO;

I feel it isn't intuitive to return -EIO here.
It'd be more straightforward to call snd_intel8x0_ich_chip_reset()
from here?

if (snd_pci_quirk_lookup(chip->pci, ich_chip_reset_mode))
return snd_intl8x0_ich_chip_reset(chip);


> + if (snd_intel8x0_ich_chip_cold_reset(chip) < 0)
> + if ((err = snd_intel8x0_ich_chip_reset(chip)) < 0)
> + return err;

Please make the change checkpatch-clean.

Could you fix and repost?


thanks,

Takashi

Subject: Re: [PATCH] ALSA: Don't cold reset AC97 codecs in some ICH chipsets

On Wed, Jan 28, 2009 at 01:06:20PM +0100, Takashi Iwai wrote:
> At Wed, 28 Jan 2009 08:02:36 -0200,
> Thadeu Lima de Souza Cascardo wrote:
> >
> > Check in a quirk list if it should do cold reset when AC97 power saving
> > is enabled. Some devices do not resume properly when cold reset,
> > although power saving works OK.
> >
> > Signed-off-by: Thadeu Lima de Souza Cascardo <[email protected]>
>
> Thanks for the patch.
> We can go better further with this patch now :)
>
> The logic is basically fine, but just a few comments...
>
> > diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
> > index 19d3391..69b3ed8 100644
> > --- a/sound/pci/intel8x0.c
> > +++ b/sound/pci/intel8x0.c
> ...
> > +static int snd_intel8x0_ich_chip_cold_reset(struct intel8x0 *chip)
> > +{
> > + unsigned int cnt;
> > /* ACLink on, 2 channels */
> > +
> > + if (snd_pci_quirk_lookup(chip->pci, ich_chip_reset_mode))
> > + return -EIO;
>
> I feel it isn't intuitive to return -EIO here.
> It'd be more straightforward to call snd_intel8x0_ich_chip_reset()
> from here?
>
> if (snd_pci_quirk_lookup(chip->pci, ich_chip_reset_mode))
> return snd_intl8x0_ich_chip_reset(chip);
>
>
> > + if (snd_intel8x0_ich_chip_cold_reset(chip) < 0)
> > + if ((err = snd_intel8x0_ich_chip_reset(chip)) < 0)
> > + return err;
>
> Please make the change checkpatch-clean.
>
> Could you fix and repost?

I did checkpatch it, but since this style is used in many places in the
intel8x0.c code, I thought I would leave it this way. Should I send a
cleanup patch too?

By the way, I have some very trivial comment typo patches lying around.
I will post them too.

>
>
> thanks,
>
> Takashi

Regards,
Cascardo.


Attachments:
(No filename) (1.66 kB)
signature.asc (197.00 B)
Digital signature
Download all attachments

2009-01-28 13:02:21

by Takashi Iwai

[permalink] [raw]
Subject: Re: [PATCH] ALSA: Don't cold reset AC97 codecs in some ICH chipsets

At Wed, 28 Jan 2009 10:27:30 -0200,
Thadeu Lima de Souza Cascardo wrote:
>
> On Wed, Jan 28, 2009 at 01:06:20PM +0100, Takashi Iwai wrote:
> > At Wed, 28 Jan 2009 08:02:36 -0200,
> > Thadeu Lima de Souza Cascardo wrote:
> > >
> > > Check in a quirk list if it should do cold reset when AC97 power saving
> > > is enabled. Some devices do not resume properly when cold reset,
> > > although power saving works OK.
> > >
> > > Signed-off-by: Thadeu Lima de Souza Cascardo <[email protected]>
> >
> > Thanks for the patch.
> > We can go better further with this patch now :)
> >
> > The logic is basically fine, but just a few comments...
> >
> > > diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
> > > index 19d3391..69b3ed8 100644
> > > --- a/sound/pci/intel8x0.c
> > > +++ b/sound/pci/intel8x0.c
> > ...
> > > +static int snd_intel8x0_ich_chip_cold_reset(struct intel8x0 *chip)
> > > +{
> > > + unsigned int cnt;
> > > /* ACLink on, 2 channels */
> > > +
> > > + if (snd_pci_quirk_lookup(chip->pci, ich_chip_reset_mode))
> > > + return -EIO;
> >
> > I feel it isn't intuitive to return -EIO here.
> > It'd be more straightforward to call snd_intel8x0_ich_chip_reset()
> > from here?
> >
> > if (snd_pci_quirk_lookup(chip->pci, ich_chip_reset_mode))
> > return snd_intl8x0_ich_chip_reset(chip);
> >
> >
> > > + if (snd_intel8x0_ich_chip_cold_reset(chip) < 0)
> > > + if ((err = snd_intel8x0_ich_chip_reset(chip)) < 0)
> > > + return err;
> >
> > Please make the change checkpatch-clean.
> >
> > Could you fix and repost?
>
> I did checkpatch it, but since this style is used in many places in the
> intel8x0.c code, I thought I would leave it this way. Should I send a
> cleanup patch too?

Just make your patch checkpatch-clean. The other parts don't have to
be changed in this case.

> By the way, I have some very trivial comment typo patches lying around.
> I will post them too.

That'll be fine.


thanks,

Takashi