2019-05-27 08:55:05 +02:00
// SPDX-License-Identifier: GPL-2.0-or-later
2005-04-16 15:20:36 -07:00
/*
* OPL4 mixer functions
* Copyright ( c ) 2003 by Clemens Ladisch < clemens @ ladisch . de >
*/
# include "opl4_local.h"
# include <sound/control.h>
2005-11-17 14:13:47 +01:00
static int snd_opl4_ctl_info ( struct snd_kcontrol * kcontrol , struct snd_ctl_elem_info * uinfo )
2005-04-16 15:20:36 -07:00
{
uinfo - > type = SNDRV_CTL_ELEM_TYPE_INTEGER ;
uinfo - > count = 2 ;
uinfo - > value . integer . min = 0 ;
uinfo - > value . integer . max = 7 ;
return 0 ;
}
2005-11-17 14:13:47 +01:00
static int snd_opl4_ctl_get ( struct snd_kcontrol * kcontrol , struct snd_ctl_elem_value * ucontrol )
2005-04-16 15:20:36 -07:00
{
2005-11-17 14:13:47 +01:00
struct snd_opl4 * opl4 = snd_kcontrol_chip ( kcontrol ) ;
2005-04-16 15:20:36 -07:00
unsigned long flags ;
u8 reg = kcontrol - > private_value ;
u8 value ;
spin_lock_irqsave ( & opl4 - > reg_lock , flags ) ;
value = snd_opl4_read ( opl4 , reg ) ;
spin_unlock_irqrestore ( & opl4 - > reg_lock , flags ) ;
ucontrol - > value . integer . value [ 0 ] = 7 - ( value & 7 ) ;
ucontrol - > value . integer . value [ 1 ] = 7 - ( ( value > > 3 ) & 7 ) ;
return 0 ;
}
2005-11-17 14:13:47 +01:00
static int snd_opl4_ctl_put ( struct snd_kcontrol * kcontrol , struct snd_ctl_elem_value * ucontrol )
2005-04-16 15:20:36 -07:00
{
2005-11-17 14:13:47 +01:00
struct snd_opl4 * opl4 = snd_kcontrol_chip ( kcontrol ) ;
2005-04-16 15:20:36 -07:00
unsigned long flags ;
u8 reg = kcontrol - > private_value ;
u8 value , old_value ;
value = ( 7 - ( ucontrol - > value . integer . value [ 0 ] & 7 ) ) |
( ( 7 - ( ucontrol - > value . integer . value [ 1 ] & 7 ) ) < < 3 ) ;
spin_lock_irqsave ( & opl4 - > reg_lock , flags ) ;
old_value = snd_opl4_read ( opl4 , reg ) ;
snd_opl4_write ( opl4 , reg , value ) ;
spin_unlock_irqrestore ( & opl4 - > reg_lock , flags ) ;
return value ! = old_value ;
}
2005-11-17 14:13:47 +01:00
static struct snd_kcontrol_new snd_opl4_controls [ ] = {
2005-04-16 15:20:36 -07:00
{
. iface = SNDRV_CTL_ELEM_IFACE_MIXER ,
. name = " FM Playback Volume " ,
. info = snd_opl4_ctl_info ,
. get = snd_opl4_ctl_get ,
. put = snd_opl4_ctl_put ,
. private_value = OPL4_REG_MIX_CONTROL_FM
} ,
{
. iface = SNDRV_CTL_ELEM_IFACE_MIXER ,
. name = " Wavetable Playback Volume " ,
. info = snd_opl4_ctl_info ,
. get = snd_opl4_ctl_get ,
. put = snd_opl4_ctl_put ,
. private_value = OPL4_REG_MIX_CONTROL_PCM
}
} ;
2005-11-17 14:13:47 +01:00
int snd_opl4_create_mixer ( struct snd_opl4 * opl4 )
2005-04-16 15:20:36 -07:00
{
2005-11-17 14:13:47 +01:00
struct snd_card * card = opl4 - > card ;
2005-04-16 15:20:36 -07:00
int i , err ;
strcat ( card - > mixername , " ,OPL4 " ) ;
for ( i = 0 ; i < 2 ; + + i ) {
err = snd_ctl_add ( card , snd_ctl_new1 ( & snd_opl4_controls [ i ] , opl4 ) ) ;
if ( err < 0 )
return err ;
}
return 0 ;
}