2005-04-16 15:20:36 -07:00
/*
* The driver for the Cirrus Logic ' s Sound Fusion CS46XX based soundcards
2007-10-15 09:50:19 +02:00
* Copyright ( c ) by Jaroslav Kysela < perex @ perex . cz >
2005-04-16 15:20:36 -07:00
*
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
*
*/
/*
NOTES :
- sometimes the sound is metallic and sibilant , unloading and
reloading the module may solve this .
*/
# include <linux/pci.h>
# include <linux/time.h>
# include <linux/init.h>
2011-07-15 13:13:37 -04:00
# include <linux/module.h>
2005-04-16 15:20:36 -07:00
# include <sound/core.h>
2012-07-02 16:37:05 +02:00
# include "cs46xx.h"
2005-04-16 15:20:36 -07:00
# include <sound/initval.h>
2007-10-15 09:50:19 +02:00
MODULE_AUTHOR ( " Jaroslav Kysela <perex@perex.cz> " ) ;
2005-04-16 15:20:36 -07:00
MODULE_DESCRIPTION ( " Cirrus Logic Sound Fusion CS46XX " ) ;
MODULE_LICENSE ( " GPL " ) ;
MODULE_SUPPORTED_DEVICE ( " {{Cirrus Logic,Sound Fusion (CS4280)}, "
" {Cirrus Logic,Sound Fusion (CS4610)}, "
" {Cirrus Logic,Sound Fusion (CS4612)}, "
" {Cirrus Logic,Sound Fusion (CS4615)}, "
" {Cirrus Logic,Sound Fusion (CS4622)}, "
" {Cirrus Logic,Sound Fusion (CS4624)}, "
" {Cirrus Logic,Sound Fusion (CS4630)}} " ) ;
static int index [ SNDRV_CARDS ] = SNDRV_DEFAULT_IDX ; /* Index 0-MAX */
static char * id [ SNDRV_CARDS ] = SNDRV_DEFAULT_STR ; /* ID for this card */
2011-12-15 13:49:36 +10:30
static bool enable [ SNDRV_CARDS ] = SNDRV_DEFAULT_ENABLE_PNP ; /* Enable this card */
static bool external_amp [ SNDRV_CARDS ] ;
static bool thinkpad [ SNDRV_CARDS ] ;
static bool mmap_valid [ SNDRV_CARDS ] = { [ 0 . . . ( SNDRV_CARDS - 1 ) ] = 1 } ;
2005-04-16 15:20:36 -07:00
module_param_array ( index , int , NULL , 0444 ) ;
MODULE_PARM_DESC ( index , " Index value for the CS46xx soundcard. " ) ;
module_param_array ( id , charp , NULL , 0444 ) ;
MODULE_PARM_DESC ( id , " ID string for the CS46xx soundcard. " ) ;
module_param_array ( enable , bool , NULL , 0444 ) ;
MODULE_PARM_DESC ( enable , " Enable CS46xx soundcard. " ) ;
module_param_array ( external_amp , bool , NULL , 0444 ) ;
MODULE_PARM_DESC ( external_amp , " Force to enable external amplifer. " ) ;
module_param_array ( thinkpad , bool , NULL , 0444 ) ;
MODULE_PARM_DESC ( thinkpad , " Force to enable Thinkpad's CLKRUN control. " ) ;
module_param_array ( mmap_valid , bool , NULL , 0444 ) ;
MODULE_PARM_DESC ( mmap_valid , " Support OSS mmap. " ) ;
2014-08-08 15:56:03 +02:00
static const struct pci_device_id snd_cs46xx_ids [ ] = {
2009-06-24 22:13:35 -07:00
{ PCI_VDEVICE ( CIRRUS , 0x6001 ) , 0 , } , /* CS4280 */
{ PCI_VDEVICE ( CIRRUS , 0x6003 ) , 0 , } , /* CS4612 */
{ PCI_VDEVICE ( CIRRUS , 0x6004 ) , 0 , } , /* CS4615 */
2005-04-16 15:20:36 -07:00
{ 0 , }
} ;
MODULE_DEVICE_TABLE ( pci , snd_cs46xx_ids ) ;
2012-12-06 12:35:10 -05:00
static int snd_card_cs46xx_probe ( struct pci_dev * pci ,
const struct pci_device_id * pci_id )
2005-04-16 15:20:36 -07:00
{
static int dev ;
2005-11-17 14:48:14 +01:00
struct snd_card * card ;
struct snd_cs46xx * chip ;
2005-04-16 15:20:36 -07:00
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 ) ;
2008-12-28 16:44:30 +01:00
if ( err < 0 )
return err ;
2005-04-16 15:20:36 -07:00
if ( ( err = snd_cs46xx_create ( card , pci ,
external_amp [ dev ] , thinkpad [ dev ] ,
& chip ) ) < 0 ) {
snd_card_free ( card ) ;
return err ;
}
2005-11-17 16:09:04 +01:00
card - > private_data = chip ;
2005-04-16 15:20:36 -07:00
chip - > accept_valid = mmap_valid [ dev ] ;
2015-01-02 12:24:47 +01:00
if ( ( err = snd_cs46xx_pcm ( chip , 0 ) ) < 0 ) {
2005-04-16 15:20:36 -07:00
snd_card_free ( card ) ;
return err ;
}
# ifdef CONFIG_SND_CS46XX_NEW_DSP
2015-01-02 12:24:47 +01:00
if ( ( err = snd_cs46xx_pcm_rear ( chip , 1 ) ) < 0 ) {
2005-04-16 15:20:36 -07:00
snd_card_free ( card ) ;
return err ;
}
2015-01-02 12:24:47 +01:00
if ( ( err = snd_cs46xx_pcm_iec958 ( chip , 2 ) ) < 0 ) {
2005-04-16 15:20:36 -07:00
snd_card_free ( card ) ;
return err ;
}
# endif
[ALSA] sound - fix .iface field of mixer control elements
Documentation,CS46xx driver,EMU10K1/EMU10K2 driver,AD1848 driver
SB16/AWE driver,CMIPCI driver,ENS1370/1+ driver,RME32 driver
RME96 driver,ICE1712 driver,ICE1724 driver,KORG1212 driver
RME HDSP driver,RME9652 driver
This patch changes .iface to SNDRV_CTL_ELEM_IFACE_MIXER whre _PCM or
_HWDEP was used in controls that are not associated with a specific PCM
(sub)stream or hwdep device, and changes some controls that got
inconsitent .iface values due to copy+paste errors. Furthermore, it
makes sure that all control that do use _PCM or _HWDEP use the correct
number in the .device field.
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
2005-07-29 15:32:58 +02:00
if ( ( err = snd_cs46xx_mixer ( chip , 2 ) ) < 0 ) {
2005-04-16 15:20:36 -07:00
snd_card_free ( card ) ;
return err ;
}
# ifdef CONFIG_SND_CS46XX_NEW_DSP
if ( chip - > nr_ac97_codecs = = 2 ) {
2015-01-02 12:24:47 +01:00
if ( ( err = snd_cs46xx_pcm_center_lfe ( chip , 3 ) ) < 0 ) {
2005-04-16 15:20:36 -07:00
snd_card_free ( card ) ;
return err ;
}
}
# endif
2015-01-02 12:24:47 +01:00
if ( ( err = snd_cs46xx_midi ( chip , 0 ) ) < 0 ) {
2005-04-16 15:20:36 -07:00
snd_card_free ( card ) ;
return err ;
}
if ( ( err = snd_cs46xx_start_dsp ( chip ) ) < 0 ) {
snd_card_free ( card ) ;
return err ;
}
snd_cs46xx_gameport ( chip ) ;
strcpy ( card - > driver , " CS46xx " ) ;
strcpy ( card - > shortname , " Sound Fusion CS46xx " ) ;
sprintf ( card - > longname , " %s at 0x%lx/0x%lx, irq %i " ,
card - > shortname ,
chip - > ba0_addr ,
chip - > ba1_addr ,
chip - > irq ) ;
if ( ( err = snd_card_register ( card ) ) < 0 ) {
snd_card_free ( card ) ;
return err ;
}
pci_set_drvdata ( pci , card ) ;
dev + + ;
return 0 ;
}
2012-12-06 12:35:10 -05:00
static void snd_card_cs46xx_remove ( struct pci_dev * pci )
2005-04-16 15:20:36 -07:00
{
snd_card_free ( pci_get_drvdata ( pci ) ) ;
}
2012-04-24 12:25:00 +02:00
static struct pci_driver cs46xx_driver = {
2011-06-10 16:20:20 +02:00
. name = KBUILD_MODNAME ,
2005-04-16 15:20:36 -07:00
. id_table = snd_cs46xx_ids ,
. probe = snd_card_cs46xx_probe ,
2012-12-06 12:35:10 -05:00
. remove = snd_card_cs46xx_remove ,
2012-08-14 18:12:04 +02:00
# ifdef CONFIG_PM_SLEEP
2012-07-02 15:20:37 +02:00
. driver = {
. pm = & snd_cs46xx_pm ,
} ,
2005-11-17 16:09:04 +01:00
# endif
2005-04-16 15:20:36 -07:00
} ;
2012-04-24 12:25:00 +02:00
module_pci_driver ( cs46xx_driver ) ;