2006-03-28 14:38:20 +04:00
/*
* AdLib FM card driver .
*/
# include <linux/kernel.h>
# include <linux/module.h>
2007-02-14 15:23:16 +03:00
# include <linux/isa.h>
2006-03-28 14:38:20 +04:00
# include <sound/core.h>
# include <sound/initval.h>
# include <sound/opl3.h>
# define CRD_NAME "AdLib FM"
2007-02-14 15:23:16 +03:00
# define DEV_NAME "adlib"
2006-03-28 14:38:20 +04:00
MODULE_DESCRIPTION ( CRD_NAME ) ;
MODULE_AUTHOR ( " Rene Herman " ) ;
MODULE_LICENSE ( " GPL " ) ;
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 ;
2006-03-28 14:38:20 +04:00
static long port [ SNDRV_CARDS ] = SNDRV_DEFAULT_PORT ;
module_param_array ( index , int , NULL , 0444 ) ;
MODULE_PARM_DESC ( index , " Index value for " CRD_NAME " soundcard. " ) ;
module_param_array ( id , charp , NULL , 0444 ) ;
MODULE_PARM_DESC ( id , " ID string for " CRD_NAME " soundcard. " ) ;
module_param_array ( enable , bool , NULL , 0444 ) ;
MODULE_PARM_DESC ( enable , " Enable " CRD_NAME " soundcard. " ) ;
module_param_array ( port , long , NULL , 0444 ) ;
MODULE_PARM_DESC ( port , " Port # for " CRD_NAME " driver. " ) ;
2012-12-06 21:35:21 +04:00
static int snd_adlib_match ( struct device * dev , unsigned int n )
2007-02-14 15:23:16 +03:00
{
if ( ! enable [ n ] )
return 0 ;
if ( port [ n ] = = SNDRV_AUTO_PORT ) {
2008-11-03 10:51:33 +03:00
dev_err ( dev , " please specify port \n " ) ;
2007-02-14 15:23:16 +03:00
return 0 ;
}
return 1 ;
}
2006-03-28 14:38:20 +04:00
static void snd_adlib_free ( struct snd_card * card )
{
release_and_free_resource ( card - > private_data ) ;
}
2012-12-06 21:35:21 +04:00
static int snd_adlib_probe ( struct device * dev , unsigned int n )
2006-03-28 14:38:20 +04:00
{
struct snd_card * card ;
struct snd_opl3 * opl3 ;
2007-02-14 15:23:16 +03:00
int error ;
2006-03-28 14:38:20 +04:00
2014-01-29 16:03:56 +04:00
error = snd_card_new ( dev , index [ n ] , id [ n ] , THIS_MODULE , 0 , & card ) ;
2008-12-28 18:43:35 +03:00
if ( error < 0 ) {
2008-11-03 10:51:33 +03:00
dev_err ( dev , " could not create card \n " ) ;
2008-12-28 18:43:35 +03:00
return error ;
2006-03-28 14:38:20 +04:00
}
2007-02-14 15:23:16 +03:00
card - > private_data = request_region ( port [ n ] , 4 , CRD_NAME ) ;
2006-03-28 14:38:20 +04:00
if ( ! card - > private_data ) {
2008-11-03 10:51:33 +03:00
dev_err ( dev , " could not grab ports \n " ) ;
2006-03-28 14:38:20 +04:00
error = - EBUSY ;
2007-02-14 15:23:16 +03:00
goto out ;
2006-03-28 14:38:20 +04:00
}
card - > private_free = snd_adlib_free ;
2007-02-14 15:23:16 +03:00
strcpy ( card - > driver , DEV_NAME ) ;
strcpy ( card - > shortname , CRD_NAME ) ;
sprintf ( card - > longname , CRD_NAME " at %#lx " , port [ n ] ) ;
error = snd_opl3_create ( card , port [ n ] , port [ n ] + 2 , OPL3_HW_AUTO , 1 , & opl3 ) ;
2006-03-28 14:38:20 +04:00
if ( error < 0 ) {
2008-11-03 10:51:33 +03:00
dev_err ( dev , " could not create OPL \n " ) ;
2007-02-14 15:23:16 +03:00
goto out ;
2006-03-28 14:38:20 +04:00
}
error = snd_opl3_hwdep_new ( opl3 , 0 , 0 , NULL ) ;
if ( error < 0 ) {
2008-11-03 10:51:33 +03:00
dev_err ( dev , " could not create FM \n " ) ;
2007-02-14 15:23:16 +03:00
goto out ;
2006-03-28 14:38:20 +04:00
}
error = snd_card_register ( card ) ;
if ( error < 0 ) {
2008-11-03 10:51:33 +03:00
dev_err ( dev , " could not register card \n " ) ;
2007-02-14 15:23:16 +03:00
goto out ;
2006-03-28 14:38:20 +04:00
}
2007-02-14 15:23:16 +03:00
dev_set_drvdata ( dev , card ) ;
2006-03-28 14:38:20 +04:00
return 0 ;
2007-02-14 15:23:16 +03:00
out : snd_card_free ( card ) ;
return error ;
2006-03-28 14:38:20 +04:00
}
2012-12-06 21:35:21 +04:00
static int snd_adlib_remove ( struct device * dev , unsigned int n )
2006-03-28 14:38:20 +04:00
{
2007-02-14 15:23:16 +03:00
snd_card_free ( dev_get_drvdata ( dev ) ) ;
2006-03-28 14:38:20 +04:00
return 0 ;
}
2007-02-14 15:23:16 +03:00
static struct isa_driver snd_adlib_driver = {
. match = snd_adlib_match ,
2006-03-28 14:38:20 +04:00
. probe = snd_adlib_probe ,
2012-12-06 21:35:21 +04:00
. remove = snd_adlib_remove ,
2006-03-28 14:38:20 +04:00
. driver = {
2007-02-14 15:23:16 +03:00
. name = DEV_NAME
2006-03-28 14:38:20 +04:00
}
} ;
static int __init alsa_card_adlib_init ( void )
{
2007-02-14 15:23:16 +03:00
return isa_register_driver ( & snd_adlib_driver , SNDRV_CARDS ) ;
2006-03-28 14:38:20 +04:00
}
static void __exit alsa_card_adlib_exit ( void )
{
2007-02-14 15:23:16 +03:00
isa_unregister_driver ( & snd_adlib_driver ) ;
2006-03-28 14:38:20 +04:00
}
module_init ( alsa_card_adlib_init ) ;
module_exit ( alsa_card_adlib_exit ) ;