2019-05-31 01:09:25 -07:00
// SPDX-License-Identifier: GPL-2.0-only
2009-05-14 08:05:58 +02:00
/*
* xfi linux driver .
*
* Copyright ( C ) 2008 , Creative Technology Ltd . All Rights Reserved .
*/
# include <linux/init.h>
# include <linux/pci.h>
# include <linux/moduleparam.h>
2009-05-14 15:14:18 +02:00
# include <linux/pci_ids.h>
2011-07-15 12:38:28 -04:00
# include <linux/module.h>
2009-05-14 08:05:58 +02:00
# include <sound/core.h>
# include <sound/initval.h>
# include "ctatc.h"
2009-06-08 18:10:32 +02:00
# include "cthardware.h"
2009-05-14 08:05:58 +02:00
MODULE_AUTHOR ( " Creative Technology Ltd " ) ;
MODULE_DESCRIPTION ( " X-Fi driver version 1.03 " ) ;
2009-06-02 09:18:26 +02:00
MODULE_LICENSE ( " GPL v2 " ) ;
2009-05-14 08:05:58 +02:00
static unsigned int reference_rate = 48000 ;
static unsigned int multiple = 2 ;
2009-05-26 18:35:27 +02:00
MODULE_PARM_DESC ( reference_rate , " Reference rate (default=48000) " ) ;
2018-05-23 12:20:59 -07:00
module_param ( reference_rate , uint , 0444 ) ;
2009-05-26 18:35:27 +02:00
MODULE_PARM_DESC ( multiple , " Rate multiplier (default=2) " ) ;
2018-05-23 12:20:59 -07:00
module_param ( multiple , uint , 0444 ) ;
2009-05-14 08:05:58 +02:00
static int index [ SNDRV_CARDS ] = SNDRV_DEFAULT_IDX ;
static char * id [ SNDRV_CARDS ] = SNDRV_DEFAULT_STR ;
2011-12-15 13:49:36 +10:30
static bool enable [ SNDRV_CARDS ] = SNDRV_DEFAULT_ENABLE_PNP ;
2010-01-14 09:19:46 +01:00
static unsigned int subsystem [ SNDRV_CARDS ] ;
2009-05-14 08:05:58 +02:00
2009-05-26 18:35:27 +02: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 09:19:46 +01:00
module_param_array ( subsystem , int , NULL , 0444 ) ;
MODULE_PARM_DESC ( subsystem , " Override subsystem ID for Creative X-Fi driver " ) ;
2009-05-26 18:35:27 +02:00
2014-08-08 15:56:03 +02:00
static const struct pci_device_id ct_pci_dev_ids [ ] = {
2009-05-14 08:05:58 +02:00
/* only X-Fi is supported, so... */
2009-06-08 18:10:32 +02: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 08:05:58 +02:00
{ 0 , }
} ;
MODULE_DEVICE_TABLE ( pci , ct_pci_dev_ids ) ;
2012-12-06 12:35:10 -05:00
static int
2009-05-14 08:05:58 +02: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 14:20:19 +01:00
err = snd_card_new ( & pci - > dev , index [ dev ] , id [ dev ] , THIS_MODULE ,
0 , & card ) ;
2009-05-14 08:05:58 +02:00
if ( err )
return err ;
if ( ( reference_rate ! = 48000 ) & & ( reference_rate ! = 44100 ) ) {
2014-09-29 14:33:26 +05:30
dev_err ( card - > dev ,
" Invalid reference_rate value %u!!! \n " ,
reference_rate ) ;
dev_err ( card - > dev ,
" The valid values for reference_rate are 48000 and 44100, Value 48000 is assumed. \n " ) ;
2009-05-14 08:05:58 +02:00
reference_rate = 48000 ;
}
2011-06-11 16:02:06 +08:00
if ( ( multiple ! = 1 ) & & ( multiple ! = 2 ) & & ( multiple ! = 4 ) ) {
2014-09-29 14:33:26 +05:30
dev_err ( card - > dev , " Invalid multiple value %u!!! \n " ,
multiple ) ;
dev_err ( card - > dev ,
" The valid values for multiple are 1, 2 and 4, Value 2 is assumed. \n " ) ;
2009-05-14 08:05:58 +02:00
multiple = 2 ;
}
2009-06-08 18:10:32 +02:00
err = ct_atc_create ( card , pci , reference_rate , multiple ,
2010-01-14 09:19:46 +01:00
pci_id - > driver_data , subsystem [ dev ] , & atc ) ;
2009-05-14 08:05:58 +02:00
if ( err < 0 )
goto error ;
card - > private_data = atc ;
/* Create alsa devices supported by this card */
2009-06-05 16:34:10 +02:00
err = ct_atc_create_alsa_devs ( atc ) ;
2009-05-14 08:05:58 +02:00
if ( err < 0 )
goto error ;
strcpy ( card - > driver , " SB-XFi " ) ;
strcpy ( card - > shortname , " Creative X-Fi " ) ;
2009-06-08 18:10:32 +02:00
snprintf ( card - > longname , sizeof ( card - > longname ) , " %s %s %s " ,
card - > shortname , atc - > chip_name , atc - > model_name ) ;
2009-05-14 08:05:58 +02: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 12:35:10 -05:00
static void ct_card_remove ( struct pci_dev * pci )
2009-05-14 08:05:58 +02:00
{
snd_card_free ( pci_get_drvdata ( pci ) ) ;
}
2012-08-14 18:12:04 +02:00
# ifdef CONFIG_PM_SLEEP
2012-07-02 15:20:37 +02:00
static int ct_card_suspend ( struct device * dev )
2009-06-22 14:52:34 +02:00
{
2012-07-02 15:20:37 +02:00
struct snd_card * card = dev_get_drvdata ( dev ) ;
2009-06-22 14:52:34 +02:00
struct ct_atc * atc = card - > private_data ;
2012-07-02 15:20:37 +02:00
return atc - > suspend ( atc ) ;
2009-06-22 14:52:34 +02:00
}
2012-07-02 15:20:37 +02:00
static int ct_card_resume ( struct device * dev )
2009-06-22 14:52:34 +02:00
{
2012-07-02 15:20:37 +02:00
struct snd_card * card = dev_get_drvdata ( dev ) ;
2009-06-22 14:52:34 +02:00
struct ct_atc * atc = card - > private_data ;
return atc - > resume ( atc ) ;
}
2012-07-02 15:20:37 +02: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 14:52:34 +02:00
# endif
2009-05-14 08:05:58 +02:00
static struct pci_driver ct_driver = {
2011-06-10 16:20:20 +02:00
. name = KBUILD_MODNAME ,
2009-05-14 08:05:58 +02:00
. id_table = ct_pci_dev_ids ,
. probe = ct_card_probe ,
2012-12-06 12:35:10 -05:00
. remove = ct_card_remove ,
2012-07-02 15:20:37 +02:00
. driver = {
. pm = CT_CARD_PM_OPS ,
} ,
2009-05-14 08:05:58 +02:00
} ;
2012-04-24 12:25:00 +02:00
module_pci_driver ( ct_driver ) ;