Re: [alsa-devel] [PATCH 1/2] ALSA: sis7019 - give slow codecs more time to reset
At Thu, 01 Dec 2011 23:26:53 -0500, David Dillow wrote:
There are some AC97 codec and board combinations that have been observed to take a very long time to respond after the cold reset has completed. In one case, more than 350 ms was required. To allow users to have sound on those platforms, we'll wait up to 500ms for the codec to become ready.
As a board may have multiple codecs, with some faster than others to reset, we add a module parameter to inform the driver which codecs should be present.
Reported-by: KotCzarny tjosko@yahoo.com Signed-off-by: David Dillow dave@thedillows.org -- This should probably be fed to stable as well.
Strangely this post didn't reach to my inbox nor alsa-devel ML... Anyway, I applied both patches now. This one includes Cc to stable, too.
thanks,
Takashi
sound/pci/sis7019.c | 64 ++++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 53 insertions(+), 11 deletions(-)
diff --git a/sound/pci/sis7019.c b/sound/pci/sis7019.c index a391e62..28dfafb 100644 --- a/sound/pci/sis7019.c +++ b/sound/pci/sis7019.c @@ -41,6 +41,7 @@ MODULE_SUPPORTED_DEVICE("{{SiS,SiS7019 Audio Accelerator}}"); static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */ static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ static int enable = 1; +static int codecs = 1;
module_param(index, int, 0444); MODULE_PARM_DESC(index, "Index value for SiS7019 Audio Accelerator."); @@ -48,6 +49,8 @@ module_param(id, charp, 0444); MODULE_PARM_DESC(id, "ID string for SiS7019 Audio Accelerator."); module_param(enable, bool, 0444); MODULE_PARM_DESC(enable, "Enable SiS7019 Audio Accelerator."); +module_param(codecs, int, 0444); +MODULE_PARM_DESC(codecs, "Set bit to indicate that codec number is expected to be present (default 1)");
static DEFINE_PCI_DEVICE_TABLE(snd_sis7019_ids) = { { PCI_DEVICE(PCI_VENDOR_ID_SI, 0x7019) }, @@ -140,6 +143,9 @@ struct sis7019 { dma_addr_t silence_dma_addr; };
+/* These values are also used by the module param 'codecs' to indicate
- which codecs should be present.
- */
#define SIS_PRIMARY_CODEC_PRESENT 0x0001 #define SIS_SECONDARY_CODEC_PRESENT 0x0002 #define SIS_TERTIARY_CODEC_PRESENT 0x0004 @@ -1078,6 +1084,7 @@ static int sis_chip_init(struct sis7019 *sis) { unsigned long io = sis->ioport; void __iomem *ioaddr = sis->ioaddr;
- unsigned long timeout; u16 status; int count; int i;
@@ -1104,21 +1111,45 @@ static int sis_chip_init(struct sis7019 *sis) while ((inw(io + SIS_AC97_STATUS) & SIS_AC97_STATUS_BUSY) && --count) udelay(1);
- /* Command complete, we can let go of the semaphore now.
*/
- outl(SIS_AC97_SEMA_RELEASE, io + SIS_AC97_SEMA);
- if (!count)
return -EIO;
- /* Now that we've finished the reset, find out what's attached.
* There are some codec/board combinations that take an extremely
* long time to come up. 350+ ms has been observed in the field,
*/* so we'll give them up to 500ms.
- status = inl(io + SIS_AC97_STATUS);
- if (status & SIS_AC97_STATUS_CODEC_READY)
sis->codecs_present |= SIS_PRIMARY_CODEC_PRESENT;
- if (status & SIS_AC97_STATUS_CODEC2_READY)
sis->codecs_present |= SIS_SECONDARY_CODEC_PRESENT;
- if (status & SIS_AC97_STATUS_CODEC3_READY)
sis->codecs_present |= SIS_TERTIARY_CODEC_PRESENT;
- /* All done, let go of the semaphore, and check for errors
- sis->codecs_present = 0;
- timeout = msecs_to_jiffies(500) + jiffies;
- while (time_before_eq(jiffies, timeout)) {
status = inl(io + SIS_AC97_STATUS);
if (status & SIS_AC97_STATUS_CODEC_READY)
sis->codecs_present |= SIS_PRIMARY_CODEC_PRESENT;
if (status & SIS_AC97_STATUS_CODEC2_READY)
sis->codecs_present |= SIS_SECONDARY_CODEC_PRESENT;
if (status & SIS_AC97_STATUS_CODEC3_READY)
sis->codecs_present |= SIS_TERTIARY_CODEC_PRESENT;
if (sis->codecs_present == codecs)
break;
msleep(1);
- }
- /* All done, check for errors. */
- outl(SIS_AC97_SEMA_RELEASE, io + SIS_AC97_SEMA);
- if (!sis->codecs_present || !count)
if (!sis->codecs_present) {
printk(KERN_ERR "sis7019: could not find any codecs\n");
return -EIO;
}
if (sis->codecs_present != codecs) {
printk(KERN_WARNING "sis7019: missing codecs, found %0x, expected %0x\n",
sis->codecs_present, codecs);
}
/* Let the hardware know that the audio driver is alive,
- and enable PCM slots on the AC-link for L/R playback (3 & 4) and
@@ -1390,6 +1421,17 @@ static int __devinit snd_sis7019_probe(struct pci_dev *pci, if (!enable) goto error_out;
- /* The user can specify which codecs should be present so that we
* can wait for them to show up if they are slow to recover from
* the AC97 cold reset. We default to a single codec, the primary.
*
* We assume that SIS_PRIMARY_*_PRESENT matches bits 0-2.
*/
- codecs &= SIS_PRIMARY_CODEC_PRESENT | SIS_SECONDARY_CODEC_PRESENT |
SIS_TERTIARY_CODEC_PRESENT;
- if (!codecs)
codecs = SIS_PRIMARY_CODEC_PRESENT;
- rc = snd_card_create(index, id, THIS_MODULE, sizeof(*sis), &card); if (rc < 0) goto error_out;
-- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
participants (1)
-
Takashi Iwai