2009-05-14 10:05:58 +04:00
/*
* xfi linux driver .
*
* Copyright ( C ) 2008 , Creative Technology Ltd . All Rights Reserved .
*
* This source file is released under GPL v2 license ( no other versions ) .
* See the COPYING file included in the main directory of this source
* distribution for the license terms and conditions .
*/
# include <linux/init.h>
# include <linux/pci.h>
# include <linux/moduleparam.h>
2009-05-14 17:14:18 +04:00
# include <linux/pci_ids.h>
2011-07-15 20:38:28 +04:00
# include <linux/module.h>
2009-05-14 10:05:58 +04:00
# include <sound/core.h>
# include <sound/initval.h>
# include "ctatc.h"
2009-06-08 20:10:32 +04:00
# include "cthardware.h"
2009-05-14 10:05:58 +04:00
MODULE_AUTHOR ( " Creative Technology Ltd " ) ;
MODULE_DESCRIPTION ( " X-Fi driver version 1.03 " ) ;
2009-06-02 11:18:26 +04:00
MODULE_LICENSE ( " GPL v2 " ) ;
2009-05-14 10:05:58 +04:00
MODULE_SUPPORTED_DEVICE ( " {{Creative Labs, Sound Blaster X-Fi} " ) ;
static unsigned int reference_rate = 48000 ;
static unsigned int multiple = 2 ;
2009-05-26 20:35:27 +04:00
MODULE_PARM_DESC ( reference_rate , " Reference rate (default=48000) " ) ;
2009-05-14 10:05:58 +04:00
module_param ( reference_rate , uint , S_IRUGO ) ;
2009-05-26 20:35:27 +04:00
MODULE_PARM_DESC ( multiple , " Rate multiplier (default=2) " ) ;
2009-05-14 10:05:58 +04:00
module_param ( multiple , uint , S_IRUGO ) ;
static int index [ SNDRV_CARDS ] = SNDRV_DEFAULT_IDX ;
static char * id [ SNDRV_CARDS ] = SNDRV_DEFAULT_STR ;
2011-12-15 07:19:36 +04:00
static bool enable [ SNDRV_CARDS ] = SNDRV_DEFAULT_ENABLE_PNP ;
2010-01-14 11:19:46 +03:00
static unsigned int subsystem [ SNDRV_CARDS ] ;
2009-05-14 10:05:58 +04:00
2009-05-26 20:35:27 +04:00
module_param_array ( index , int , NULL , 0444 ) ;
MODULE_PARM_DESC ( index , " Index value for Creative X-Fi driver " ) ;
module_param_array ( id , charp , NULL , 0444 ) ;
MODULE_PARM_DESC ( id , " ID string for Creative X-Fi driver " ) ;
module_param_array ( enable , bool , NULL , 0444 ) ;
MODULE_PARM_DESC ( enable , " Enable Creative X-Fi driver " ) ;
2010-01-14 11:19:46 +03:00
module_param_array ( subsystem , int , NULL , 0444 ) ;
MODULE_PARM_DESC ( subsystem , " Override subsystem ID for Creative X-Fi driver " ) ;
2009-05-26 20:35:27 +04:00
2010-02-06 01:21:03 +03:00
static DEFINE_PCI_DEVICE_TABLE ( ct_pci_dev_ids ) = {
2009-05-14 10:05:58 +04:00
/* only X-Fi is supported, so... */
2009-06-08 20:10:32 +04:00
{ PCI_DEVICE ( PCI_VENDOR_ID_CREATIVE , PCI_DEVICE_ID_CREATIVE_20K1 ) ,
. driver_data = ATC20K1 ,
} ,
{ PCI_DEVICE ( PCI_VENDOR_ID_CREATIVE , PCI_DEVICE_ID_CREATIVE_20K2 ) ,
. driver_data = ATC20K2 ,
} ,
2009-05-14 10:05:58 +04:00
{ 0 , }
} ;
MODULE_DEVICE_TABLE ( pci , ct_pci_dev_ids ) ;
2012-12-06 21:35:10 +04:00
static int
2009-05-14 10:05:58 +04:00
ct_card_probe ( struct pci_dev * pci , const struct pci_device_id * pci_id )
{
static int dev ;
struct snd_card * card ;
struct ct_atc * atc ;
int err ;
if ( dev > = SNDRV_CARDS )
return - ENODEV ;
if ( ! enable [ dev ] ) {
dev + + ;
return - ENOENT ;
}
2014-01-29 17:20:19 +04:00
err = snd_card_new ( & pci - > dev , index [ dev ] , id [ dev ] , THIS_MODULE ,
0 , & card ) ;
2009-05-14 10:05:58 +04:00
if ( err )
return err ;
if ( ( reference_rate ! = 48000 ) & & ( reference_rate ! = 44100 ) ) {
2009-05-14 17:19:30 +04:00
printk ( KERN_ERR " ctxfi: Invalid reference_rate value %u!!! \n " ,
reference_rate ) ;
printk ( KERN_ERR " ctxfi: The valid values for reference_rate "
" are 48000 and 44100, Value 48000 is assumed. \n " ) ;
2009-05-14 10:05:58 +04:00
reference_rate = 48000 ;
}
2011-06-11 12:02:06 +04:00
if ( ( multiple ! = 1 ) & & ( multiple ! = 2 ) & & ( multiple ! = 4 ) ) {
2009-05-14 17:19:30 +04:00
printk ( KERN_ERR " ctxfi: Invalid multiple value %u!!! \n " ,
multiple ) ;
printk ( KERN_ERR " ctxfi: The valid values for multiple are "
2011-06-11 12:02:06 +04:00
" 1, 2 and 4, Value 2 is assumed. \n " ) ;
2009-05-14 10:05:58 +04:00
multiple = 2 ;
}
2009-06-08 20:10:32 +04:00
err = ct_atc_create ( card , pci , reference_rate , multiple ,
2010-01-14 11:19:46 +03:00
pci_id - > driver_data , subsystem [ dev ] , & atc ) ;
2009-05-14 10:05:58 +04:00
if ( err < 0 )
goto error ;
card - > private_data = atc ;
/* Create alsa devices supported by this card */
2009-06-05 18:34:10 +04:00
err = ct_atc_create_alsa_devs ( atc ) ;
2009-05-14 10:05:58 +04:00
if ( err < 0 )
goto error ;
strcpy ( card - > driver , " SB-XFi " ) ;
strcpy ( card - > shortname , " Creative X-Fi " ) ;
2009-06-08 20:10:32 +04:00
snprintf ( card - > longname , sizeof ( card - > longname ) , " %s %s %s " ,
card - > shortname , atc - > chip_name , atc - > model_name ) ;
2009-05-14 10:05:58 +04:00
err = snd_card_register ( card ) ;
if ( err < 0 )
goto error ;
pci_set_drvdata ( pci , card ) ;
dev + + ;
return 0 ;
error :
snd_card_free ( card ) ;
return err ;
}
2012-12-06 21:35:10 +04:00
static void ct_card_remove ( struct pci_dev * pci )
2009-05-14 10:05:58 +04:00
{
snd_card_free ( pci_get_drvdata ( pci ) ) ;
}
2012-08-14 20:12:04 +04:00
# ifdef CONFIG_PM_SLEEP
2012-07-02 17:20:37 +04:00
static int ct_card_suspend ( struct device * dev )
2009-06-22 16:52:34 +04:00
{
2012-07-02 17:20:37 +04:00
struct snd_card * card = dev_get_drvdata ( dev ) ;
2009-06-22 16:52:34 +04:00
struct ct_atc * atc = card - > private_data ;
2012-07-02 17:20:37 +04:00
return atc - > suspend ( atc ) ;
2009-06-22 16:52:34 +04:00
}
2012-07-02 17:20:37 +04:00
static int ct_card_resume ( struct device * dev )
2009-06-22 16:52:34 +04:00
{
2012-07-02 17:20:37 +04:00
struct snd_card * card = dev_get_drvdata ( dev ) ;
2009-06-22 16:52:34 +04:00
struct ct_atc * atc = card - > private_data ;
return atc - > resume ( atc ) ;
}
2012-07-02 17:20:37 +04:00
static SIMPLE_DEV_PM_OPS ( ct_card_pm , ct_card_suspend , ct_card_resume ) ;
# define CT_CARD_PM_OPS &ct_card_pm
# else
# define CT_CARD_PM_OPS NULL
2009-06-22 16:52:34 +04:00
# endif
2009-05-14 10:05:58 +04:00
static struct pci_driver ct_driver = {
2011-06-10 18:20:20 +04:00
. name = KBUILD_MODNAME ,
2009-05-14 10:05:58 +04:00
. id_table = ct_pci_dev_ids ,
. probe = ct_card_probe ,
2012-12-06 21:35:10 +04:00
. remove = ct_card_remove ,
2012-07-02 17:20:37 +04:00
. driver = {
. pm = CT_CARD_PM_OPS ,
} ,
2009-05-14 10:05:58 +04:00
} ;
2012-04-24 14:25:00 +04:00
module_pci_driver ( ct_driver ) ;