@ -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 500 ms .
*/
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 ;