2008-03-03 10:53:54 +01:00
/*
* PC - Speaker driver for Linux
*
* Mixer implementation .
* Copyright ( C ) 2001 - 2008 Stas Sergeev
*/
# include <sound/core.h>
# include <sound/control.h>
# include "pcsp.h"
static int pcsp_enable_info ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_info * uinfo )
{
uinfo - > type = SNDRV_CTL_ELEM_TYPE_BOOLEAN ;
uinfo - > count = 1 ;
uinfo - > value . integer . min = 0 ;
uinfo - > value . integer . max = 1 ;
return 0 ;
}
static int pcsp_enable_get ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
struct snd_pcsp * chip = snd_kcontrol_chip ( kcontrol ) ;
ucontrol - > value . integer . value [ 0 ] = chip - > enable ;
return 0 ;
}
static int pcsp_enable_put ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
struct snd_pcsp * chip = snd_kcontrol_chip ( kcontrol ) ;
int changed = 0 ;
int enab = ucontrol - > value . integer . value [ 0 ] ;
if ( enab ! = chip - > enable ) {
chip - > enable = enab ;
changed = 1 ;
}
return changed ;
}
static int pcsp_treble_info ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_info * uinfo )
{
struct snd_pcsp * chip = snd_kcontrol_chip ( kcontrol ) ;
uinfo - > type = SNDRV_CTL_ELEM_TYPE_ENUMERATED ;
uinfo - > count = 1 ;
uinfo - > value . enumerated . items = chip - > max_treble + 1 ;
if ( uinfo - > value . enumerated . item > chip - > max_treble )
uinfo - > value . enumerated . item = chip - > max_treble ;
2009-05-14 08:49:13 -07:00
sprintf ( uinfo - > value . enumerated . name , " %lu " ,
2009-05-20 17:05:52 +02:00
( unsigned long ) PCSP_CALC_RATE ( uinfo - > value . enumerated . item ) ) ;
2008-03-03 10:53:54 +01:00
return 0 ;
}
static int pcsp_treble_get ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
struct snd_pcsp * chip = snd_kcontrol_chip ( kcontrol ) ;
ucontrol - > value . enumerated . item [ 0 ] = chip - > treble ;
return 0 ;
}
static int pcsp_treble_put ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
struct snd_pcsp * chip = snd_kcontrol_chip ( kcontrol ) ;
int changed = 0 ;
int treble = ucontrol - > value . enumerated . item [ 0 ] ;
if ( treble ! = chip - > treble ) {
chip - > treble = treble ;
# if PCSP_DEBUG
2009-10-30 11:51:24 +01:00
printk ( KERN_INFO " PCSP: rate set to %li \n " , PCSP_RATE ( ) ) ;
2008-03-03 10:53:54 +01:00
# endif
changed = 1 ;
}
return changed ;
}
static int pcsp_pcspkr_info ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_info * uinfo )
{
uinfo - > type = SNDRV_CTL_ELEM_TYPE_BOOLEAN ;
uinfo - > count = 1 ;
uinfo - > value . integer . min = 0 ;
uinfo - > value . integer . max = 1 ;
return 0 ;
}
static int pcsp_pcspkr_get ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
struct snd_pcsp * chip = snd_kcontrol_chip ( kcontrol ) ;
ucontrol - > value . integer . value [ 0 ] = chip - > pcspkr ;
return 0 ;
}
static int pcsp_pcspkr_put ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
struct snd_pcsp * chip = snd_kcontrol_chip ( kcontrol ) ;
int changed = 0 ;
int spkr = ucontrol - > value . integer . value [ 0 ] ;
if ( spkr ! = chip - > pcspkr ) {
chip - > pcspkr = spkr ;
changed = 1 ;
}
return changed ;
}
# define PCSP_MIXER_CONTROL(ctl_type, ctl_name) \
{ \
. iface = SNDRV_CTL_ELEM_IFACE_MIXER , \
. name = ctl_name , \
. info = pcsp_ # # ctl_type # # _info , \
. get = pcsp_ # # ctl_type # # _get , \
. put = pcsp_ # # ctl_type # # _put , \
}
2009-11-01 11:13:19 +01:00
static struct snd_kcontrol_new __devinitdata snd_pcsp_controls_pcm [ ] = {
2008-03-03 10:53:54 +01:00
PCSP_MIXER_CONTROL ( enable , " Master Playback Switch " ) ,
PCSP_MIXER_CONTROL ( treble , " BaseFRQ Playback Volume " ) ,
2009-11-01 11:13:19 +01:00
} ;
static struct snd_kcontrol_new __devinitdata snd_pcsp_controls_spkr [ ] = {
2009-11-03 15:47:25 +01:00
PCSP_MIXER_CONTROL ( pcspkr , " Beep Playback Switch " ) ,
2008-03-03 10:53:54 +01:00
} ;
2009-11-01 11:13:19 +01:00
static int __devinit snd_pcsp_ctls_add ( struct snd_pcsp * chip ,
struct snd_kcontrol_new * ctls , int num )
2008-03-03 10:53:54 +01:00
{
int i , err ;
2009-11-01 11:13:19 +01:00
struct snd_card * card = chip - > card ;
for ( i = 0 ; i < num ; i + + ) {
err = snd_ctl_add ( card , snd_ctl_new1 ( ctls + i , chip ) ) ;
if ( err < 0 )
return err ;
}
return 0 ;
}
int __devinit snd_pcsp_new_mixer ( struct snd_pcsp * chip , int nopcm )
{
int err ;
struct snd_card * card = chip - > card ;
2008-03-03 10:53:54 +01:00
2009-11-01 11:13:19 +01:00
if ( ! nopcm ) {
err = snd_pcsp_ctls_add ( chip , snd_pcsp_controls_pcm ,
ARRAY_SIZE ( snd_pcsp_controls_pcm ) ) ;
2008-03-03 10:53:54 +01:00
if ( err < 0 )
return err ;
}
2009-11-01 11:13:19 +01:00
err = snd_pcsp_ctls_add ( chip , snd_pcsp_controls_spkr ,
ARRAY_SIZE ( snd_pcsp_controls_spkr ) ) ;
if ( err < 0 )
return err ;
2008-03-03 10:53:54 +01:00
strcpy ( card - > mixername , " PC-Speaker " ) ;
return 0 ;
}