2019-05-27 08:55:05 +02:00
// SPDX-License-Identifier: GPL-2.0-or-later
2005-04-16 15:20:36 -07:00
/*
* Generic driver for CS4231 chips
2007-10-15 09:50:19 +02:00
* Copyright ( c ) by Jaroslav Kysela < perex @ perex . cz >
2005-04-16 15:20:36 -07:00
* Originally the CS4232 / CS4232A driver , modified for use on CS4231 by
* Tugrul Galatali < galatalt @ stuy . edu >
*/
# include <linux/init.h>
2005-11-17 17:00:41 +01:00
# include <linux/err.h>
2007-02-14 13:23:38 +01:00
# include <linux/isa.h>
2005-04-16 15:20:36 -07:00
# include <linux/time.h>
# include <linux/wait.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>
2008-07-31 21:02:42 +02:00
# include <sound/wss.h>
2005-04-16 15:20:36 -07:00
# include <sound/mpu401.h>
# include <sound/initval.h>
2007-02-14 13:23:38 +01:00
# define CRD_NAME "Generic CS4231"
# define DEV_NAME "cs4231"
MODULE_DESCRIPTION ( CRD_NAME ) ;
2007-10-15 09:50:19 +02:00
MODULE_AUTHOR ( " Jaroslav Kysela <perex@perex.cz> " ) ;
2005-04-16 15:20:36 -07:00
MODULE_LICENSE ( " GPL " ) ;
MODULE_SUPPORTED_DEVICE ( " {{Crystal Semiconductors,CS4231}} " ) ;
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 ; /* Enable this card */
2005-04-16 15:20:36 -07:00
static long port [ SNDRV_CARDS ] = SNDRV_DEFAULT_PORT ; /* PnP setup */
static long mpu_port [ SNDRV_CARDS ] = SNDRV_DEFAULT_PORT ; /* PnP setup */
static int irq [ SNDRV_CARDS ] = SNDRV_DEFAULT_IRQ ; /* 5,7,9,11,12,15 */
static int mpu_irq [ SNDRV_CARDS ] = SNDRV_DEFAULT_IRQ ; /* 9,11,12,15 */
static int dma1 [ SNDRV_CARDS ] = SNDRV_DEFAULT_DMA ; /* 0,1,3,5,6,7 */
static int dma2 [ SNDRV_CARDS ] = SNDRV_DEFAULT_DMA ; /* 0,1,3,5,6,7 */
module_param_array ( index , int , NULL , 0444 ) ;
2007-02-14 13:23:38 +01:00
MODULE_PARM_DESC ( index , " Index value for " CRD_NAME " soundcard. " ) ;
2005-04-16 15:20:36 -07:00
module_param_array ( id , charp , NULL , 0444 ) ;
2007-02-14 13:23:38 +01:00
MODULE_PARM_DESC ( id , " ID string for " CRD_NAME " soundcard. " ) ;
2005-04-16 15:20:36 -07:00
module_param_array ( enable , bool , NULL , 0444 ) ;
2007-02-14 13:23:38 +01:00
MODULE_PARM_DESC ( enable , " Enable " CRD_NAME " soundcard. " ) ;
2017-04-04 16:54:30 +01:00
module_param_hw_array ( port , long , ioport , NULL , 0444 ) ;
2007-02-14 13:23:38 +01:00
MODULE_PARM_DESC ( port , " Port # for " CRD_NAME " driver. " ) ;
2017-04-04 16:54:30 +01:00
module_param_hw_array ( mpu_port , long , ioport , NULL , 0444 ) ;
2007-02-14 13:23:38 +01:00
MODULE_PARM_DESC ( mpu_port , " MPU-401 port # for " CRD_NAME " driver. " ) ;
2017-04-04 16:54:30 +01:00
module_param_hw_array ( irq , int , irq , NULL , 0444 ) ;
2007-02-14 13:23:38 +01:00
MODULE_PARM_DESC ( irq , " IRQ # for " CRD_NAME " driver. " ) ;
2017-04-04 16:54:30 +01:00
module_param_hw_array ( mpu_irq , int , irq , NULL , 0444 ) ;
2007-02-14 13:23:38 +01:00
MODULE_PARM_DESC ( mpu_irq , " MPU-401 IRQ # for " CRD_NAME " driver. " ) ;
2017-04-04 16:54:30 +01:00
module_param_hw_array ( dma1 , int , dma , NULL , 0444 ) ;
2007-02-14 13:23:38 +01:00
MODULE_PARM_DESC ( dma1 , " DMA1 # for " CRD_NAME " driver. " ) ;
2017-04-04 16:54:30 +01:00
module_param_hw_array ( dma2 , int , dma , NULL , 0444 ) ;
2007-02-14 13:23:38 +01:00
MODULE_PARM_DESC ( dma2 , " DMA2 # for " CRD_NAME " driver. " ) ;
2005-04-16 15:20:36 -07:00
2012-12-06 12:35:21 -05:00
static int snd_cs4231_match ( struct device * dev , unsigned int n )
2007-02-14 13:23:38 +01:00
{
if ( ! enable [ n ] )
return 0 ;
2005-12-07 09:13:42 +01:00
2007-02-14 13:23:38 +01:00
if ( port [ n ] = = SNDRV_AUTO_PORT ) {
2008-11-03 08:51:33 +01:00
dev_err ( dev , " please specify port \n " ) ;
2007-02-14 13:23:38 +01:00
return 0 ;
}
if ( irq [ n ] = = SNDRV_AUTO_IRQ ) {
2008-11-03 08:51:33 +01:00
dev_err ( dev , " please specify irq \n " ) ;
2007-02-14 13:23:38 +01:00
return 0 ;
}
if ( dma1 [ n ] = = SNDRV_AUTO_DMA ) {
2008-11-03 08:51:33 +01:00
dev_err ( dev , " please specify dma1 \n " ) ;
2007-02-14 13:23:38 +01:00
return 0 ;
}
return 1 ;
}
2005-04-16 15:20:36 -07:00
2012-12-06 12:35:21 -05:00
static int snd_cs4231_probe ( struct device * dev , unsigned int n )
2005-04-16 15:20:36 -07:00
{
2005-11-17 14:30:42 +01:00
struct snd_card * card ;
2008-07-31 21:03:41 +02:00
struct snd_wss * chip ;
2007-02-14 13:23:38 +01:00
int error ;
2005-04-16 15:20:36 -07:00
2014-01-29 13:03:56 +01:00
error = snd_card_new ( dev , index [ n ] , id [ n ] , THIS_MODULE , 0 , & card ) ;
2008-12-28 16:43:35 +01:00
if ( error < 0 )
return error ;
2007-02-14 13:23:38 +01:00
2008-07-31 21:03:41 +02:00
error = snd_wss_create ( card , port [ n ] , - 1 , irq [ n ] , dma1 [ n ] , dma2 [ n ] ,
WSS_HW_DETECT , 0 , & chip ) ;
2007-02-14 13:23:38 +01:00
if ( error < 0 )
goto out ;
2005-11-17 17:00:41 +01:00
card - > private_data = chip ;
2005-04-16 15:20:36 -07:00
2015-01-02 12:24:43 +01:00
error = snd_wss_pcm ( chip , 0 ) ;
2007-02-14 13:23:38 +01:00
if ( error < 0 )
goto out ;
2005-04-16 15:20:36 -07:00
2017-07-18 13:48:05 +02:00
strlcpy ( card - > driver , " CS4231 " , sizeof ( card - > driver ) ) ;
strlcpy ( card - > shortname , chip - > pcm - > name , sizeof ( card - > shortname ) ) ;
if ( dma2 [ n ] < 0 )
snprintf ( card - > longname , sizeof ( card - > longname ) ,
" %s at 0x%lx, irq %d, dma %d " ,
chip - > pcm - > name , chip - > port , irq [ n ] , dma1 [ n ] ) ;
else
snprintf ( card - > longname , sizeof ( card - > longname ) ,
" %s at 0x%lx, irq %d, dma %d&%d " ,
chip - > pcm - > name , chip - > port , irq [ n ] , dma1 [ n ] , dma2 [ n ] ) ;
2007-02-14 13:23:38 +01:00
2008-07-31 21:03:41 +02:00
error = snd_wss_mixer ( chip ) ;
2007-02-14 13:23:38 +01:00
if ( error < 0 )
goto out ;
2015-01-02 12:24:43 +01:00
error = snd_wss_timer ( chip , 0 ) ;
2007-02-14 13:23:38 +01:00
if ( error < 0 )
goto out ;
if ( mpu_port [ n ] > 0 & & mpu_port [ n ] ! = SNDRV_AUTO_PORT ) {
if ( mpu_irq [ n ] = = SNDRV_AUTO_IRQ )
mpu_irq [ n ] = - 1 ;
2005-04-16 15:20:36 -07:00
if ( snd_mpu401_uart_new ( card , 0 , MPU401_HW_CS4232 ,
2007-02-14 13:23:38 +01:00
mpu_port [ n ] , 0 , mpu_irq [ n ] ,
2005-04-16 15:20:36 -07:00
NULL ) < 0 )
2008-11-03 08:51:33 +01:00
dev_warn ( dev , " MPU401 not detected \n " ) ;
2005-04-16 15:20:36 -07:00
}
[ALSA] Add snd_card_set_generic_dev() call to ISA drivers
ISA,CMI8330 driver,ES18xx driver,OPL3SA2 driver,Sound Galaxy driver
Sound Scape driver,AD1848 driver,CS4231 driver,CS4236+ driver
ES1688 driver,GUS Classic driver,GUS Extreme driver,GUS MAX driver
AMD InterWave driver,Opti9xx drivers,SB16/AWE driver,SB8 driver
Wavefront drivers
- Added snd_card_set_generic_dev() call.
- Added SND_GENERIC_DRIVER to Kconfig.
- Clean up the error path in probe if necessary.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2005-09-05 17:19:20 +02:00
2007-02-14 13:23:38 +01:00
error = snd_card_register ( card ) ;
if ( error < 0 )
goto out ;
2005-11-17 17:00:41 +01:00
2007-02-14 13:23:38 +01:00
dev_set_drvdata ( dev , card ) ;
2005-04-16 15:20:36 -07:00
return 0 ;
[ALSA] Add snd_card_set_generic_dev() call to ISA drivers
ISA,CMI8330 driver,ES18xx driver,OPL3SA2 driver,Sound Galaxy driver
Sound Scape driver,AD1848 driver,CS4231 driver,CS4236+ driver
ES1688 driver,GUS Classic driver,GUS Extreme driver,GUS MAX driver
AMD InterWave driver,Opti9xx drivers,SB16/AWE driver,SB8 driver
Wavefront drivers
- Added snd_card_set_generic_dev() call.
- Added SND_GENERIC_DRIVER to Kconfig.
- Clean up the error path in probe if necessary.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2005-09-05 17:19:20 +02:00
2007-02-14 13:23:38 +01:00
out : snd_card_free ( card ) ;
return error ;
2005-04-16 15:20:36 -07:00
}
2012-12-06 12:35:21 -05:00
static int snd_cs4231_remove ( struct device * dev , unsigned int n )
2005-11-17 17:00:41 +01:00
{
2007-02-14 13:23:38 +01:00
snd_card_free ( dev_get_drvdata ( dev ) ) ;
2005-11-17 17:00:41 +01:00
return 0 ;
}
# ifdef CONFIG_PM
2007-02-14 13:23:38 +01:00
static int snd_cs4231_suspend ( struct device * dev , unsigned int n , pm_message_t state )
2005-04-16 15:20:36 -07:00
{
2007-02-14 13:23:38 +01:00
struct snd_card * card = dev_get_drvdata ( dev ) ;
2008-07-31 21:03:41 +02:00
struct snd_wss * chip = card - > private_data ;
2007-02-14 13:23:38 +01:00
2005-11-17 17:00:41 +01:00
snd_power_change_state ( card , SNDRV_CTL_POWER_D3hot ) ;
chip - > suspend ( chip ) ;
return 0 ;
}
2005-04-16 15:20:36 -07:00
2007-02-14 13:23:38 +01:00
static int snd_cs4231_resume ( struct device * dev , unsigned int n )
2005-11-17 17:00:41 +01:00
{
2007-02-14 13:23:38 +01:00
struct snd_card * card = dev_get_drvdata ( dev ) ;
2008-07-31 21:03:41 +02:00
struct snd_wss * chip = card - > private_data ;
2007-02-14 13:23:38 +01:00
2005-11-17 17:00:41 +01:00
chip - > resume ( chip ) ;
snd_power_change_state ( card , SNDRV_CTL_POWER_D0 ) ;
return 0 ;
}
# endif
2007-02-14 13:23:38 +01:00
static struct isa_driver snd_cs4231_driver = {
. match = snd_cs4231_match ,
2005-11-17 17:00:41 +01:00
. probe = snd_cs4231_probe ,
2012-12-06 12:35:21 -05:00
. remove = snd_cs4231_remove ,
2005-11-17 17:00:41 +01:00
# ifdef CONFIG_PM
. suspend = snd_cs4231_suspend ,
. resume = snd_cs4231_resume ,
# endif
. driver = {
2007-02-14 13:23:38 +01:00
. name = DEV_NAME
}
2005-11-17 17:00:41 +01:00
} ;
2016-05-31 11:55:29 -04:00
module_isa_driver ( snd_cs4231_driver , SNDRV_CARDS ) ;