2005-04-17 02:20:36 +04:00
/*
* Universal Interface for Intel High Definition Audio Codec
*
* Local helper functions
*
* Copyright ( c ) 2004 Takashi Iwai < tiwai @ suse . de >
*
* 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 .
*/
# ifndef __SOUND_HDA_LOCAL_H
# define __SOUND_HDA_LOCAL_H
/*
* for mixer controls
*/
2009-01-20 15:07:55 +03:00
# define HDA_COMPOSE_AMP_VAL_OFS(nid,chs,idx,dir,ofs) \
( ( nid ) | ( ( chs ) < < 16 ) | ( ( dir ) < < 18 ) | ( ( idx ) < < 19 ) | ( ( ofs ) < < 23 ) )
2007-07-27 18:52:19 +04:00
# define HDA_COMPOSE_AMP_VAL(nid,chs,idx,dir) \
2009-01-20 15:07:55 +03:00
HDA_COMPOSE_AMP_VAL_OFS ( nid , chs , idx , dir , 0 )
2005-11-02 20:26:49 +03:00
/* mono volume with index (index=0,1,...) (channel=1,2) */
2005-04-17 02:20:36 +04:00
# define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \
{ . iface = SNDRV_CTL_ELEM_IFACE_MIXER , . name = xname , . index = xcidx , \
2006-07-05 19:39:49 +04:00
. access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK , \
2005-04-17 02:20:36 +04:00
. info = snd_hda_mixer_amp_volume_info , \
. get = snd_hda_mixer_amp_volume_get , \
. put = snd_hda_mixer_amp_volume_put , \
2006-08-17 18:23:07 +04:00
. tlv = { . c = snd_hda_mixer_amp_tlv } , \
2005-04-17 02:20:36 +04:00
. private_value = HDA_COMPOSE_AMP_VAL ( nid , channel , xindex , direction ) }
2005-11-02 20:26:49 +03:00
/* stereo volume with index */
2005-04-17 02:20:36 +04:00
# define HDA_CODEC_VOLUME_IDX(xname, xcidx, nid, xindex, direction) \
HDA_CODEC_VOLUME_MONO_IDX ( xname , xcidx , nid , 3 , xindex , direction )
2005-11-02 20:26:49 +03:00
/* mono volume */
2005-04-17 02:20:36 +04:00
# define HDA_CODEC_VOLUME_MONO(xname, nid, channel, xindex, direction) \
HDA_CODEC_VOLUME_MONO_IDX ( xname , 0 , nid , channel , xindex , direction )
2005-11-02 20:26:49 +03:00
/* stereo volume */
2005-04-17 02:20:36 +04:00
# define HDA_CODEC_VOLUME(xname, nid, xindex, direction) \
HDA_CODEC_VOLUME_MONO ( xname , nid , 3 , xindex , direction )
2005-11-02 20:26:49 +03:00
/* mono mute switch with index (index=0,1,...) (channel=1,2) */
2005-04-17 02:20:36 +04:00
# define HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \
{ . iface = SNDRV_CTL_ELEM_IFACE_MIXER , . name = xname , . index = xcidx , \
. info = snd_hda_mixer_amp_switch_info , \
. get = snd_hda_mixer_amp_switch_get , \
. put = snd_hda_mixer_amp_switch_put , \
. private_value = HDA_COMPOSE_AMP_VAL ( nid , channel , xindex , direction ) }
2005-11-02 20:26:49 +03:00
/* stereo mute switch with index */
2005-04-17 02:20:36 +04:00
# define HDA_CODEC_MUTE_IDX(xname, xcidx, nid, xindex, direction) \
HDA_CODEC_MUTE_MONO_IDX ( xname , xcidx , nid , 3 , xindex , direction )
2005-11-02 20:26:49 +03:00
/* mono mute switch */
2005-04-17 02:20:36 +04:00
# define HDA_CODEC_MUTE_MONO(xname, nid, channel, xindex, direction) \
HDA_CODEC_MUTE_MONO_IDX ( xname , 0 , nid , channel , xindex , direction )
2005-11-02 20:26:49 +03:00
/* stereo mute switch */
2005-04-17 02:20:36 +04:00
# define HDA_CODEC_MUTE(xname, nid, xindex, direction) \
HDA_CODEC_MUTE_MONO ( xname , nid , 3 , xindex , direction )
2009-10-21 16:48:23 +04:00
/* special beep mono mute switch with index (index=0,1,...) (channel=1,2) */
# define HDA_CODEC_MUTE_BEEP_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \
{ . iface = SNDRV_CTL_ELEM_IFACE_MIXER , . name = xname , . index = xcidx , \
. info = snd_hda_mixer_amp_switch_info , \
. get = snd_hda_mixer_amp_switch_get , \
. put = snd_hda_mixer_amp_switch_put_beep , \
. private_value = HDA_COMPOSE_AMP_VAL ( nid , channel , xindex , direction ) }
/* special beep mono mute switch */
# define HDA_CODEC_MUTE_BEEP_MONO(xname, nid, channel, xindex, direction) \
HDA_CODEC_MUTE_BEEP_MONO_IDX ( xname , 0 , nid , channel , xindex , direction )
/* special beep stereo mute switch */
# define HDA_CODEC_MUTE_BEEP(xname, nid, xindex, direction) \
HDA_CODEC_MUTE_BEEP_MONO ( xname , nid , 3 , xindex , direction )
2005-04-17 02:20:36 +04:00
2007-07-27 18:52:19 +04:00
int snd_hda_mixer_amp_volume_info ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_info * uinfo ) ;
int snd_hda_mixer_amp_volume_get ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol ) ;
int snd_hda_mixer_amp_volume_put ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol ) ;
int snd_hda_mixer_amp_tlv ( struct snd_kcontrol * kcontrol , int op_flag ,
unsigned int size , unsigned int __user * tlv ) ;
int snd_hda_mixer_amp_switch_info ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_info * uinfo ) ;
int snd_hda_mixer_amp_switch_get ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol ) ;
int snd_hda_mixer_amp_switch_put ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol ) ;
2009-10-21 16:48:23 +04:00
int snd_hda_mixer_amp_switch_put_beep ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol ) ;
2006-03-01 16:16:17 +03:00
/* lowlevel accessor with caching; use carefully */
int snd_hda_codec_amp_read ( struct hda_codec * codec , hda_nid_t nid , int ch ,
int direction , int index ) ;
int snd_hda_codec_amp_update ( struct hda_codec * codec , hda_nid_t nid , int ch ,
int direction , int idx , int mask , int val ) ;
2007-08-10 19:11:07 +04:00
int snd_hda_codec_amp_stereo ( struct hda_codec * codec , hda_nid_t nid ,
int dir , int idx , int mask , int val ) ;
2007-08-10 19:21:45 +04:00
# ifdef SND_HDA_NEEDS_RESUME
2007-08-10 19:03:40 +04:00
void snd_hda_codec_resume_amp ( struct hda_codec * codec ) ;
2007-08-10 19:09:26 +04:00
# endif
2005-04-17 02:20:36 +04:00
2008-01-10 18:53:55 +03:00
void snd_hda_set_vmaster_tlv ( struct hda_codec * codec , hda_nid_t nid , int dir ,
unsigned int * tlv ) ;
struct snd_kcontrol * snd_hda_find_mixer_ctl ( struct hda_codec * codec ,
const char * name ) ;
int snd_hda_add_vmaster ( struct hda_codec * codec , char * name ,
unsigned int * tlv , const char * * slaves ) ;
2009-02-23 18:57:04 +03:00
int snd_hda_codec_reset ( struct hda_codec * codec ) ;
2008-01-10 18:53:55 +03:00
2007-08-10 19:11:07 +04:00
/* amp value bits */
# define HDA_AMP_MUTE 0x80
# define HDA_AMP_UNMUTE 0x00
# define HDA_AMP_VOLMASK 0x7f
2005-11-02 20:26:49 +03:00
/* mono switch binding multiple inputs */
# define HDA_BIND_MUTE_MONO(xname, nid, channel, indices, direction) \
{ . iface = SNDRV_CTL_ELEM_IFACE_MIXER , . name = xname , . index = 0 , \
. info = snd_hda_mixer_amp_switch_info , \
. get = snd_hda_mixer_bind_switch_get , \
. put = snd_hda_mixer_bind_switch_put , \
. private_value = HDA_COMPOSE_AMP_VAL ( nid , channel , indices , direction ) }
/* stereo switch binding multiple inputs */
2007-07-27 18:52:19 +04:00
# define HDA_BIND_MUTE(xname,nid,indices,dir) \
HDA_BIND_MUTE_MONO ( xname , nid , 3 , indices , dir )
2005-11-02 20:26:49 +03:00
2007-07-27 18:52:19 +04:00
int snd_hda_mixer_bind_switch_get ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol ) ;
int snd_hda_mixer_bind_switch_put ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol ) ;
2005-11-02 20:26:49 +03:00
2007-07-27 21:02:40 +04:00
/* more generic bound controls */
struct hda_ctl_ops {
snd_kcontrol_info_t * info ;
snd_kcontrol_get_t * get ;
snd_kcontrol_put_t * put ;
snd_kcontrol_tlv_rw_t * tlv ;
} ;
extern struct hda_ctl_ops snd_hda_bind_vol ; /* for bind-volume with TLV */
extern struct hda_ctl_ops snd_hda_bind_sw ; /* for bind-switch */
struct hda_bind_ctls {
struct hda_ctl_ops * ops ;
2009-02-26 00:28:45 +03:00
unsigned long values [ ] ;
2007-07-27 21:02:40 +04:00
} ;
int snd_hda_mixer_bind_ctls_info ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_info * uinfo ) ;
int snd_hda_mixer_bind_ctls_get ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol ) ;
int snd_hda_mixer_bind_ctls_put ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol ) ;
int snd_hda_mixer_bind_tlv ( struct snd_kcontrol * kcontrol , int op_flag ,
unsigned int size , unsigned int __user * tlv ) ;
# define HDA_BIND_VOL(xname, bindrec) \
{ . iface = SNDRV_CTL_ELEM_IFACE_MIXER , \
. name = xname , \
. access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK , \
. info = snd_hda_mixer_bind_ctls_info , \
. get = snd_hda_mixer_bind_ctls_get , \
. put = snd_hda_mixer_bind_ctls_put , \
. tlv = { . c = snd_hda_mixer_bind_tlv } , \
. private_value = ( long ) ( bindrec ) }
# define HDA_BIND_SW(xname, bindrec) \
{ . iface = SNDRV_CTL_ELEM_IFACE_MIXER , \
. name = xname , \
. info = snd_hda_mixer_bind_ctls_info , \
. get = snd_hda_mixer_bind_ctls_get , \
. put = snd_hda_mixer_bind_ctls_put , \
. private_value = ( long ) ( bindrec ) }
/*
* SPDIF I / O
*/
2005-04-17 02:20:36 +04:00
int snd_hda_create_spdif_out_ctls ( struct hda_codec * codec , hda_nid_t nid ) ;
int snd_hda_create_spdif_in_ctls ( struct hda_codec * codec , hda_nid_t nid ) ;
/*
* input MUX helper
*/
2005-11-21 18:33:22 +03:00
# define HDA_MAX_NUM_INPUTS 16
2005-04-17 02:20:36 +04:00
struct hda_input_mux_item {
const char * label ;
unsigned int index ;
} ;
struct hda_input_mux {
unsigned int num_items ;
struct hda_input_mux_item items [ HDA_MAX_NUM_INPUTS ] ;
} ;
2007-07-27 18:52:19 +04:00
int snd_hda_input_mux_info ( const struct hda_input_mux * imux ,
struct snd_ctl_elem_info * uinfo ) ;
int snd_hda_input_mux_put ( struct hda_codec * codec ,
const struct hda_input_mux * imux ,
2005-11-17 16:57:47 +03:00
struct snd_ctl_elem_value * ucontrol , hda_nid_t nid ,
2005-04-17 02:20:36 +04:00
unsigned int * cur_val ) ;
2005-11-17 16:57:47 +03:00
/*
2005-11-17 13:06:29 +03:00
* Channel mode helper
*/
struct hda_channel_mode {
int channels ;
const struct hda_verb * sequence ;
} ;
2007-07-27 18:52:19 +04:00
int snd_hda_ch_mode_info ( struct hda_codec * codec ,
struct snd_ctl_elem_info * uinfo ,
const struct hda_channel_mode * chmode ,
int num_chmodes ) ;
int snd_hda_ch_mode_get ( struct hda_codec * codec ,
struct snd_ctl_elem_value * ucontrol ,
const struct hda_channel_mode * chmode ,
int num_chmodes ,
2005-11-17 13:06:29 +03:00
int max_channels ) ;
2007-07-27 18:52:19 +04:00
int snd_hda_ch_mode_put ( struct hda_codec * codec ,
struct snd_ctl_elem_value * ucontrol ,
const struct hda_channel_mode * chmode ,
int num_chmodes ,
2005-11-17 13:06:29 +03:00
int * max_channelsp ) ;
2005-04-17 02:20:36 +04:00
/*
* Multi - channel / digital - out PCM helper
*/
enum { HDA_FRONT , HDA_REAR , HDA_CLFE , HDA_SIDE } ; /* index for dac_nidx */
enum { HDA_DIG_NONE , HDA_DIG_EXCLUSIVE , HDA_DIG_ANALOG_DUP } ; /* dig_out_used */
struct hda_multi_out {
int num_dacs ; /* # of DACs, must be more than 1 */
hda_nid_t * dac_nids ; /* DAC list */
hda_nid_t hp_nid ; /* optional DAC for HP, 0 when not exists */
2006-03-21 13:24:42 +03:00
hda_nid_t extra_out_nid [ 3 ] ; /* optional DACs, 0 when not exists */
2005-04-17 02:20:36 +04:00
hda_nid_t dig_out_nid ; /* digital out audio widget */
2009-02-06 10:02:27 +03:00
hda_nid_t * slave_dig_outs ;
2005-04-17 02:20:36 +04:00
int max_channels ; /* currently supported analog channels */
int dig_out_used ; /* current usage of digital out (HDA_DIG_XXX) */
2007-10-26 14:35:56 +04:00
int no_share_stream ; /* don't share a stream with multiple pins */
2008-02-12 20:37:26 +03:00
int share_spdif ; /* share SPDIF pin */
/* PCM information for both analog and SPDIF DACs */
unsigned int analog_rates ;
unsigned int analog_maxbps ;
u64 analog_formats ;
unsigned int spdif_rates ;
unsigned int spdif_maxbps ;
u64 spdif_formats ;
2005-04-17 02:20:36 +04:00
} ;
2008-02-12 20:37:26 +03:00
int snd_hda_create_spdif_share_sw ( struct hda_codec * codec ,
struct hda_multi_out * mout ) ;
2007-07-27 18:52:19 +04:00
int snd_hda_multi_out_dig_open ( struct hda_codec * codec ,
struct hda_multi_out * mout ) ;
int snd_hda_multi_out_dig_close ( struct hda_codec * codec ,
struct hda_multi_out * mout ) ;
2007-04-05 16:51:48 +04:00
int snd_hda_multi_out_dig_prepare ( struct hda_codec * codec ,
struct hda_multi_out * mout ,
unsigned int stream_tag ,
unsigned int format ,
struct snd_pcm_substream * substream ) ;
2009-02-13 13:32:28 +03:00
int snd_hda_multi_out_dig_cleanup ( struct hda_codec * codec ,
struct hda_multi_out * mout ) ;
2007-07-27 18:52:19 +04:00
int snd_hda_multi_out_analog_open ( struct hda_codec * codec ,
struct hda_multi_out * mout ,
2008-02-12 20:37:26 +03:00
struct snd_pcm_substream * substream ,
struct hda_pcm_stream * hinfo ) ;
2007-07-27 18:52:19 +04:00
int snd_hda_multi_out_analog_prepare ( struct hda_codec * codec ,
struct hda_multi_out * mout ,
2005-04-17 02:20:36 +04:00
unsigned int stream_tag ,
unsigned int format ,
2005-11-17 16:57:47 +03:00
struct snd_pcm_substream * substream ) ;
2007-07-27 18:52:19 +04:00
int snd_hda_multi_out_analog_cleanup ( struct hda_codec * codec ,
struct hda_multi_out * mout ) ;
2005-04-17 02:20:36 +04:00
/*
* generic codec parser
*/
2007-10-19 10:13:40 +04:00
# ifdef CONFIG_SND_HDA_GENERIC
2005-04-17 02:20:36 +04:00
int snd_hda_parse_generic_codec ( struct hda_codec * codec ) ;
2007-10-19 10:13:40 +04:00
# else
static inline int snd_hda_parse_generic_codec ( struct hda_codec * codec )
{
return - ENODEV ;
}
# endif
2005-04-17 02:20:36 +04:00
/*
* generic proc interface
*/
# ifdef CONFIG_PROC_FS
int snd_hda_codec_proc_new ( struct hda_codec * codec ) ;
# else
static inline int snd_hda_codec_proc_new ( struct hda_codec * codec ) { return 0 ; }
# endif
2008-11-18 06:47:51 +03:00
# define SND_PRINT_RATES_ADVISED_BUFSIZE 80
void snd_print_pcm_rates ( int pcm , char * buf , int buflen ) ;
2008-11-19 10:14:02 +03:00
# define SND_PRINT_BITS_ADVISED_BUFSIZE 16
void snd_print_pcm_bits ( int pcm , char * buf , int buflen ) ;
2005-04-17 02:20:36 +04:00
/*
* Misc
*/
2006-11-24 19:07:44 +03:00
int snd_hda_check_board_config ( struct hda_codec * codec , int num_configs ,
const char * * modelnames ,
const struct snd_pci_quirk * pci_list ) ;
2008-08-11 12:18:39 +04:00
int snd_hda_check_board_codec_sid_config ( struct hda_codec * codec ,
int num_configs , const char * * models ,
const struct snd_pci_quirk * tbl ) ;
2007-07-27 18:52:19 +04:00
int snd_hda_add_new_ctls ( struct hda_codec * codec ,
struct snd_kcontrol_new * knew ) ;
2005-04-17 02:20:36 +04:00
/*
* unsolicited event handler
*/
# define HDA_UNSOL_QUEUE_SIZE 64
struct hda_bus_unsolicited {
/* ring buffer */
u32 queue [ HDA_UNSOL_QUEUE_SIZE * 2 ] ;
unsigned int rp , wp ;
/* workqueue */
struct work_struct work ;
2006-11-22 17:57:56 +03:00
struct hda_bus * bus ;
2005-04-17 02:20:36 +04:00
} ;
2005-06-13 16:16:38 +04:00
/*
* Helper for automatic ping configuration
*/
enum {
AUTO_PIN_MIC ,
AUTO_PIN_FRONT_MIC ,
AUTO_PIN_LINE ,
AUTO_PIN_FRONT_LINE ,
AUTO_PIN_CD ,
AUTO_PIN_AUX ,
AUTO_PIN_LAST
} ;
2007-04-23 19:16:21 +04:00
enum {
AUTO_PIN_LINE_OUT ,
AUTO_PIN_SPEAKER_OUT ,
AUTO_PIN_HP_OUT
} ;
2005-12-07 15:56:29 +03:00
extern const char * auto_pin_cfg_labels [ AUTO_PIN_LAST ] ;
2007-10-22 19:20:10 +04:00
# define AUTO_CFG_MAX_OUTS 5
2005-06-13 16:16:38 +04:00
struct auto_pin_cfg {
int line_outs ;
2007-10-22 19:20:10 +04:00
/* sorted in the order of Front/Surr/CLFE/Side */
hda_nid_t line_out_pins [ AUTO_CFG_MAX_OUTS ] ;
2006-03-21 13:24:42 +03:00
int speaker_outs ;
2007-10-22 19:20:10 +04:00
hda_nid_t speaker_pins [ AUTO_CFG_MAX_OUTS ] ;
2006-09-20 19:10:27 +04:00
int hp_outs ;
2007-04-23 19:16:21 +04:00
int line_out_type ; /* AUTO_PIN_XXX_OUT */
2007-10-22 19:20:10 +04:00
hda_nid_t hp_pins [ AUTO_CFG_MAX_OUTS ] ;
2005-06-13 16:16:38 +04:00
hda_nid_t input_pins [ AUTO_PIN_LAST ] ;
2009-02-11 13:35:15 +03:00
int dig_outs ;
hda_nid_t dig_out_pins [ 2 ] ;
2005-06-13 16:16:38 +04:00
hda_nid_t dig_in_pin ;
2008-01-24 13:48:01 +03:00
hda_nid_t mono_out_pin ;
2009-02-11 13:35:15 +03:00
int dig_out_type [ 2 ] ; /* HDA_PCM_TYPE_XXX */
2009-01-20 20:24:13 +03:00
int dig_in_type ; /* HDA_PCM_TYPE_XXX */
2005-06-13 16:16:38 +04:00
} ;
2007-07-27 18:52:19 +04:00
# define get_defcfg_connect(cfg) \
( ( cfg & AC_DEFCFG_PORT_CONN ) > > AC_DEFCFG_PORT_CONN_SHIFT )
# define get_defcfg_association(cfg) \
( ( cfg & AC_DEFCFG_DEF_ASSOC ) > > AC_DEFCFG_ASSOC_SHIFT )
# define get_defcfg_location(cfg) \
( ( cfg & AC_DEFCFG_LOCATION ) > > AC_DEFCFG_LOCATION_SHIFT )
# define get_defcfg_sequence(cfg) \
( cfg & AC_DEFCFG_SEQUENCE )
# define get_defcfg_device(cfg) \
( ( cfg & AC_DEFCFG_DEVICE ) > > AC_DEFCFG_DEVICE_SHIFT )
int snd_hda_parse_pin_def_config ( struct hda_codec * codec ,
struct auto_pin_cfg * cfg ,
2005-12-05 21:42:22 +03:00
hda_nid_t * ignore_nids ) ;
2005-06-13 16:16:38 +04:00
2005-11-17 13:09:23 +03:00
/* amp values */
# define AMP_IN_MUTE(idx) (0x7080 | ((idx)<<8))
# define AMP_IN_UNMUTE(idx) (0x7000 | ((idx)<<8))
2008-10-29 10:15:30 +03:00
# define AMP_OUT_MUTE 0xb080
# define AMP_OUT_UNMUTE 0xb000
# define AMP_OUT_ZERO 0xb000
2005-11-17 13:09:23 +03:00
/* pinctl values */
2008-09-14 03:54:59 +04:00
# define PIN_IN (AC_PINCTL_IN_EN)
2008-10-29 10:15:30 +03:00
# define PIN_VREFHIZ (AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ)
2008-09-14 03:54:59 +04:00
# define PIN_VREF50 (AC_PINCTL_IN_EN | AC_PINCTL_VREF_50)
2008-10-29 10:15:30 +03:00
# define PIN_VREFGRD (AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD)
2008-09-14 03:54:59 +04:00
# define PIN_VREF80 (AC_PINCTL_IN_EN | AC_PINCTL_VREF_80)
2008-10-29 10:15:30 +03:00
# define PIN_VREF100 (AC_PINCTL_IN_EN | AC_PINCTL_VREF_100)
# define PIN_OUT (AC_PINCTL_OUT_EN)
2008-09-14 03:54:59 +04:00
# define PIN_HP (AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN)
# define PIN_HP_AMP (AC_PINCTL_HP_EN)
2005-11-17 13:09:23 +03:00
2005-11-21 18:33:22 +03:00
/*
* get widget capabilities
*/
static inline u32 get_wcaps ( struct hda_codec * codec , hda_nid_t nid )
{
if ( nid < codec - > start_nid | |
nid > = codec - > start_nid + codec - > num_nodes )
2008-01-22 17:37:13 +03:00
return 0 ;
2005-11-21 18:33:22 +03:00
return codec - > wcaps [ nid - codec - > start_nid ] ;
}
2009-07-27 14:54:26 +04:00
/* get the widget type from widget capability bits */
# define get_wcaps_type(wcaps) (((wcaps) & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT)
2009-08-24 05:50:46 +04:00
static inline unsigned int get_wcaps_channels ( u32 wcaps )
{
unsigned int chans ;
chans = ( wcaps & AC_WCAP_CHAN_CNT_EXT ) > > 13 ;
chans = ( ( chans < < 1 ) | 1 ) + 1 ;
return chans ;
}
2008-01-24 13:49:21 +03:00
u32 query_amp_caps ( struct hda_codec * codec , hda_nid_t nid , int direction ) ;
2007-05-29 21:01:37 +04:00
int snd_hda_override_amp_caps ( struct hda_codec * codec , hda_nid_t nid , int dir ,
unsigned int caps ) ;
2009-03-23 15:07:47 +03:00
u32 snd_hda_query_pin_caps ( struct hda_codec * codec , hda_nid_t nid ) ;
2005-11-21 18:33:22 +03:00
2008-07-30 17:01:45 +04:00
int snd_hda_ctl_add ( struct hda_codec * codec , struct snd_kcontrol * kctl ) ;
void snd_hda_ctls_clear ( struct hda_codec * codec ) ;
2007-07-27 20:58:06 +04:00
/*
* hwdep interface
*/
2008-07-30 17:01:46 +04:00
# ifdef CONFIG_SND_HDA_HWDEP
2007-07-27 20:58:06 +04:00
int snd_hda_create_hwdep ( struct hda_codec * codec ) ;
2008-07-30 17:01:46 +04:00
# else
static inline int snd_hda_create_hwdep ( struct hda_codec * codec ) { return 0 ; }
# endif
2007-07-27 20:58:06 +04:00
2009-11-12 12:01:18 +03:00
# if defined(CONFIG_SND_HDA_POWER_SAVE) && defined(CONFIG_SND_HDA_HWDEP)
2009-11-11 11:34:25 +03:00
int snd_hda_hwdep_add_power_sysfs ( struct hda_codec * codec ) ;
# else
static inline int snd_hda_hwdep_add_power_sysfs ( struct hda_codec * codec )
{
return 0 ;
}
# endif
2008-11-21 11:26:20 +03:00
# ifdef CONFIG_SND_HDA_RECONFIG
int snd_hda_hwdep_add_sysfs ( struct hda_codec * codec ) ;
# else
static inline int snd_hda_hwdep_add_sysfs ( struct hda_codec * codec )
{
return 0 ;
}
# endif
2009-03-02 16:25:17 +03:00
# ifdef CONFIG_SND_HDA_RECONFIG
const char * snd_hda_get_hint ( struct hda_codec * codec , const char * key ) ;
int snd_hda_get_bool_hint ( struct hda_codec * codec , const char * key ) ;
# else
static inline
const char * snd_hda_get_hint ( struct hda_codec * codec , const char * key )
{
return NULL ;
}
static inline
int snd_hda_get_bool_hint ( struct hda_codec * codec , const char * key )
{
return - ENOENT ;
}
# endif
2007-08-10 19:21:45 +04:00
/*
* power - management
*/
# ifdef CONFIG_SND_HDA_POWER_SAVE
void snd_hda_schedule_power_save ( struct hda_codec * codec ) ;
struct hda_amp_list {
hda_nid_t nid ;
unsigned char dir ;
unsigned char idx ;
} ;
struct hda_loopback_check {
struct hda_amp_list * amplist ;
int power_on ;
} ;
int snd_hda_check_amp_list_power ( struct hda_codec * codec ,
struct hda_loopback_check * check ,
hda_nid_t nid ) ;
# endif /* CONFIG_SND_HDA_POWER_SAVE */
2008-09-11 17:49:39 +04:00
/*
* AMP control callbacks
*/
/* retrieve parameters from private_value */
# define get_amp_nid(kc) ((kc)->private_value & 0xffff)
# define get_amp_channels(kc) (((kc)->private_value >> 16) & 0x3)
# define get_amp_direction(kc) (((kc)->private_value >> 18) & 0x1)
# define get_amp_index(kc) (((kc)->private_value >> 19) & 0xf)
2009-01-20 15:07:55 +03:00
# define get_amp_offset(kc) (((kc)->private_value >> 23) & 0x3f)
2008-09-11 17:49:39 +04:00
2008-11-18 06:47:52 +03:00
/*
* CEA Short Audio Descriptor data
*/
struct cea_sad {
int channels ;
int format ; /* (format == 0) indicates invalid SAD */
int rates ;
int sample_bits ; /* for LPCM */
int max_bitrate ; /* for AC3...ATRAC */
int profile ; /* for WMAPRO */
} ;
# define ELD_FIXED_BYTES 20
# define ELD_MAX_MNL 16
# define ELD_MAX_SAD 16
/*
* ELD : EDID Like Data
*/
2008-11-19 10:14:00 +03:00
struct hdmi_eld {
2008-11-18 06:47:52 +03:00
int eld_size ;
int baseline_len ;
int eld_ver ; /* (eld_ver == 0) indicates invalid ELD */
int cea_edid_ver ;
char monitor_name [ ELD_MAX_MNL + 1 ] ;
int manufacture_id ;
int product_id ;
u64 port_id ;
int support_hdcp ;
int support_ai ;
int conn_type ;
int aud_synch_delay ;
int spk_alloc ;
int sad_count ;
struct cea_sad sad [ ELD_MAX_SAD ] ;
2008-11-21 11:11:50 +03:00
# ifdef CONFIG_PROC_FS
struct snd_info_entry * proc_entry ;
# endif
2008-11-18 06:47:52 +03:00
} ;
int snd_hdmi_get_eld_size ( struct hda_codec * codec , hda_nid_t nid ) ;
2008-11-19 10:14:00 +03:00
int snd_hdmi_get_eld ( struct hdmi_eld * , struct hda_codec * , hda_nid_t ) ;
void snd_hdmi_show_eld ( struct hdmi_eld * eld ) ;
2008-11-18 06:47:52 +03:00
2008-11-18 06:47:53 +03:00
# ifdef CONFIG_PROC_FS
2009-10-30 13:44:26 +03:00
int snd_hda_eld_proc_new ( struct hda_codec * codec , struct hdmi_eld * eld ,
int index ) ;
2008-11-21 11:11:50 +03:00
void snd_hda_eld_proc_free ( struct hda_codec * codec , struct hdmi_eld * eld ) ;
2008-11-18 06:47:53 +03:00
# else
2008-11-21 10:54:54 +03:00
static inline int snd_hda_eld_proc_new ( struct hda_codec * codec ,
2009-10-30 13:44:26 +03:00
struct hdmi_eld * eld ,
int index )
2008-11-18 06:47:53 +03:00
{
return 0 ;
}
2008-11-21 11:11:50 +03:00
static inline void snd_hda_eld_proc_free ( struct hda_codec * codec ,
struct hdmi_eld * eld )
{
}
2008-11-18 06:47:53 +03:00
# endif
2008-11-19 03:56:16 +03:00
# define SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE 80
void snd_print_channel_allocation ( int spk_alloc , char * buf , int buflen ) ;
2005-04-17 02:20:36 +04:00
# endif /* __SOUND_HDA_LOCAL_H */