2005-04-17 02:20:36 +04:00
/*
2005-04-14 15:35:51 +04:00
* HD audio interface patch for AD1981HD , AD1983 , AD1986A
2005-04-17 02:20:36 +04:00
*
* Copyright ( c ) 2005 Takashi Iwai < tiwai @ suse . de >
*
* This driver 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 driver 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
*/
# include <sound/driver.h>
# include <linux/init.h>
# include <linux/delay.h>
# include <linux/slab.h>
# include <linux/pci.h>
# include <sound/core.h>
# include "hda_codec.h"
# include "hda_local.h"
2005-04-14 15:35:51 +04:00
struct ad198x_spec {
2005-11-17 16:57:47 +03:00
struct snd_kcontrol_new * mixers [ 5 ] ;
2005-11-02 20:26:49 +03:00
int num_mixers ;
const struct hda_verb * init_verbs [ 3 ] ; /* initialization verbs
* don ' t forget NULL termination !
*/
unsigned int num_init_verbs ;
/* playback */
struct hda_multi_out multiout ; /* playback set-up
* max_channels , dacs must be set
* dig_out_nid and hp_nid are optional
*/
/* capture */
unsigned int num_adc_nids ;
hda_nid_t * adc_nids ;
hda_nid_t dig_in_nid ; /* digital-in NID; optional */
/* capture source */
2005-04-14 15:35:51 +04:00
const struct hda_input_mux * input_mux ;
2005-11-02 20:26:49 +03:00
unsigned int cur_mux [ 3 ] ;
/* channel model */
2005-11-17 13:06:29 +03:00
const struct hda_channel_mode * channel_mode ;
2005-11-02 20:26:49 +03:00
int num_channel_mode ;
/* PCM information */
struct hda_pcm pcm_rec [ 2 ] ; /* used in alc_build_pcms() */
struct semaphore amp_mutex ; /* PCM volume/mute control mutex */
2005-04-14 15:35:51 +04:00
unsigned int spdif_route ;
2005-04-17 02:20:36 +04:00
} ;
2005-04-14 15:35:51 +04:00
/*
* input MUX handling ( common part )
*/
2005-11-17 16:57:47 +03:00
static int ad198x_mux_enum_info ( struct snd_kcontrol * kcontrol , struct snd_ctl_elem_info * uinfo )
2005-04-14 15:35:51 +04:00
{
struct hda_codec * codec = snd_kcontrol_chip ( kcontrol ) ;
struct ad198x_spec * spec = codec - > spec ;
return snd_hda_input_mux_info ( spec - > input_mux , uinfo ) ;
}
2005-11-17 16:57:47 +03:00
static int ad198x_mux_enum_get ( struct snd_kcontrol * kcontrol , struct snd_ctl_elem_value * ucontrol )
2005-04-14 15:35:51 +04:00
{
struct hda_codec * codec = snd_kcontrol_chip ( kcontrol ) ;
struct ad198x_spec * spec = codec - > spec ;
2005-11-02 20:26:49 +03:00
unsigned int adc_idx = snd_ctl_get_ioffidx ( kcontrol , & ucontrol - > id ) ;
2005-04-14 15:35:51 +04:00
2005-11-02 20:26:49 +03:00
ucontrol - > value . enumerated . item [ 0 ] = spec - > cur_mux [ adc_idx ] ;
2005-04-14 15:35:51 +04:00
return 0 ;
}
2005-11-17 16:57:47 +03:00
static int ad198x_mux_enum_put ( struct snd_kcontrol * kcontrol , struct snd_ctl_elem_value * ucontrol )
2005-04-14 15:35:51 +04:00
{
struct hda_codec * codec = snd_kcontrol_chip ( kcontrol ) ;
struct ad198x_spec * spec = codec - > spec ;
2005-11-02 20:26:49 +03:00
unsigned int adc_idx = snd_ctl_get_ioffidx ( kcontrol , & ucontrol - > id ) ;
2005-04-14 15:35:51 +04:00
return snd_hda_input_mux_put ( codec , spec - > input_mux , ucontrol ,
2005-11-02 20:26:49 +03:00
spec - > adc_nids [ adc_idx ] , & spec - > cur_mux [ adc_idx ] ) ;
2005-04-14 15:35:51 +04:00
}
/*
* initialization ( common callbacks )
*/
static int ad198x_init ( struct hda_codec * codec )
{
struct ad198x_spec * spec = codec - > spec ;
2005-11-02 20:26:49 +03:00
int i ;
for ( i = 0 ; i < spec - > num_init_verbs ; i + + )
snd_hda_sequence_write ( codec , spec - > init_verbs [ i ] ) ;
2005-04-14 15:35:51 +04:00
return 0 ;
}
static int ad198x_build_controls ( struct hda_codec * codec )
{
struct ad198x_spec * spec = codec - > spec ;
2005-11-02 20:26:49 +03:00
unsigned int i ;
2005-04-14 15:35:51 +04:00
int err ;
2005-11-02 20:26:49 +03:00
for ( i = 0 ; i < spec - > num_mixers ; i + + ) {
err = snd_hda_add_new_ctls ( codec , spec - > mixers [ i ] ) ;
if ( err < 0 )
return err ;
}
if ( spec - > multiout . dig_out_nid ) {
2005-04-14 15:35:51 +04:00
err = snd_hda_create_spdif_out_ctls ( codec , spec - > multiout . dig_out_nid ) ;
2005-11-02 20:26:49 +03:00
if ( err < 0 )
return err ;
}
if ( spec - > dig_in_nid ) {
err = snd_hda_create_spdif_in_ctls ( codec , spec - > dig_in_nid ) ;
if ( err < 0 )
return err ;
}
2005-04-14 15:35:51 +04:00
return 0 ;
}
/*
* Analog playback callbacks
*/
static int ad198x_playback_pcm_open ( struct hda_pcm_stream * hinfo ,
struct hda_codec * codec ,
2005-11-17 16:57:47 +03:00
struct snd_pcm_substream * substream )
2005-04-14 15:35:51 +04:00
{
struct ad198x_spec * spec = codec - > spec ;
return snd_hda_multi_out_analog_open ( codec , & spec - > multiout , substream ) ;
}
static int ad198x_playback_pcm_prepare ( struct hda_pcm_stream * hinfo ,
struct hda_codec * codec ,
unsigned int stream_tag ,
unsigned int format ,
2005-11-17 16:57:47 +03:00
struct snd_pcm_substream * substream )
2005-04-14 15:35:51 +04:00
{
struct ad198x_spec * spec = codec - > spec ;
return snd_hda_multi_out_analog_prepare ( codec , & spec - > multiout , stream_tag ,
format , substream ) ;
}
static int ad198x_playback_pcm_cleanup ( struct hda_pcm_stream * hinfo ,
struct hda_codec * codec ,
2005-11-17 16:57:47 +03:00
struct snd_pcm_substream * substream )
2005-04-14 15:35:51 +04:00
{
struct ad198x_spec * spec = codec - > spec ;
return snd_hda_multi_out_analog_cleanup ( codec , & spec - > multiout ) ;
}
/*
* Digital out
*/
static int ad198x_dig_playback_pcm_open ( struct hda_pcm_stream * hinfo ,
struct hda_codec * codec ,
2005-11-17 16:57:47 +03:00
struct snd_pcm_substream * substream )
2005-04-14 15:35:51 +04:00
{
struct ad198x_spec * spec = codec - > spec ;
return snd_hda_multi_out_dig_open ( codec , & spec - > multiout ) ;
}
static int ad198x_dig_playback_pcm_close ( struct hda_pcm_stream * hinfo ,
struct hda_codec * codec ,
2005-11-17 16:57:47 +03:00
struct snd_pcm_substream * substream )
2005-04-14 15:35:51 +04:00
{
struct ad198x_spec * spec = codec - > spec ;
return snd_hda_multi_out_dig_close ( codec , & spec - > multiout ) ;
}
/*
* Analog capture
*/
static int ad198x_capture_pcm_prepare ( struct hda_pcm_stream * hinfo ,
struct hda_codec * codec ,
unsigned int stream_tag ,
unsigned int format ,
2005-11-17 16:57:47 +03:00
struct snd_pcm_substream * substream )
2005-04-14 15:35:51 +04:00
{
struct ad198x_spec * spec = codec - > spec ;
2005-11-02 20:26:49 +03:00
snd_hda_codec_setup_stream ( codec , spec - > adc_nids [ substream - > number ] ,
stream_tag , 0 , format ) ;
2005-04-14 15:35:51 +04:00
return 0 ;
}
static int ad198x_capture_pcm_cleanup ( struct hda_pcm_stream * hinfo ,
struct hda_codec * codec ,
2005-11-17 16:57:47 +03:00
struct snd_pcm_substream * substream )
2005-04-14 15:35:51 +04:00
{
struct ad198x_spec * spec = codec - > spec ;
2005-11-02 20:26:49 +03:00
snd_hda_codec_setup_stream ( codec , spec - > adc_nids [ substream - > number ] ,
0 , 0 , 0 ) ;
2005-04-14 15:35:51 +04:00
return 0 ;
}
/*
*/
static struct hda_pcm_stream ad198x_pcm_analog_playback = {
. substreams = 1 ,
. channels_min = 2 ,
2005-11-02 20:26:49 +03:00
. channels_max = 6 , /* changed later */
2005-04-14 15:35:51 +04:00
. nid = 0 , /* fill later */
. ops = {
. open = ad198x_playback_pcm_open ,
. prepare = ad198x_playback_pcm_prepare ,
. cleanup = ad198x_playback_pcm_cleanup
} ,
} ;
static struct hda_pcm_stream ad198x_pcm_analog_capture = {
2005-11-02 20:26:49 +03:00
. substreams = 1 ,
2005-04-14 15:35:51 +04:00
. channels_min = 2 ,
. channels_max = 2 ,
. nid = 0 , /* fill later */
. ops = {
. prepare = ad198x_capture_pcm_prepare ,
. cleanup = ad198x_capture_pcm_cleanup
} ,
} ;
static struct hda_pcm_stream ad198x_pcm_digital_playback = {
. substreams = 1 ,
. channels_min = 2 ,
. channels_max = 2 ,
. nid = 0 , /* fill later */
. ops = {
. open = ad198x_dig_playback_pcm_open ,
. close = ad198x_dig_playback_pcm_close
} ,
} ;
2005-11-02 20:26:49 +03:00
static struct hda_pcm_stream ad198x_pcm_digital_capture = {
. substreams = 1 ,
. channels_min = 2 ,
. channels_max = 2 ,
/* NID is set in alc_build_pcms */
} ;
2005-04-14 15:35:51 +04:00
static int ad198x_build_pcms ( struct hda_codec * codec )
{
struct ad198x_spec * spec = codec - > spec ;
struct hda_pcm * info = spec - > pcm_rec ;
codec - > num_pcms = 1 ;
codec - > pcm_info = info ;
info - > name = " AD198x Analog " ;
info - > stream [ SNDRV_PCM_STREAM_PLAYBACK ] = ad198x_pcm_analog_playback ;
info - > stream [ SNDRV_PCM_STREAM_PLAYBACK ] . channels_max = spec - > multiout . max_channels ;
info - > stream [ SNDRV_PCM_STREAM_PLAYBACK ] . nid = spec - > multiout . dac_nids [ 0 ] ;
info - > stream [ SNDRV_PCM_STREAM_CAPTURE ] = ad198x_pcm_analog_capture ;
2005-11-02 20:26:49 +03:00
info - > stream [ SNDRV_PCM_STREAM_CAPTURE ] . substreams = spec - > num_adc_nids ;
info - > stream [ SNDRV_PCM_STREAM_CAPTURE ] . nid = spec - > adc_nids [ 0 ] ;
2005-04-14 15:35:51 +04:00
if ( spec - > multiout . dig_out_nid ) {
info + + ;
codec - > num_pcms + + ;
info - > name = " AD198x Digital " ;
info - > stream [ SNDRV_PCM_STREAM_PLAYBACK ] = ad198x_pcm_digital_playback ;
info - > stream [ SNDRV_PCM_STREAM_PLAYBACK ] . nid = spec - > multiout . dig_out_nid ;
2005-11-02 20:26:49 +03:00
if ( spec - > dig_in_nid ) {
info - > stream [ SNDRV_PCM_STREAM_CAPTURE ] = ad198x_pcm_digital_capture ;
info - > stream [ SNDRV_PCM_STREAM_CAPTURE ] . nid = spec - > dig_in_nid ;
}
2005-04-14 15:35:51 +04:00
}
return 0 ;
}
static void ad198x_free ( struct hda_codec * codec )
{
kfree ( codec - > spec ) ;
}
# ifdef CONFIG_PM
static int ad198x_resume ( struct hda_codec * codec )
{
struct ad198x_spec * spec = codec - > spec ;
2005-11-02 20:26:49 +03:00
int i ;
2005-04-14 15:35:51 +04:00
ad198x_init ( codec ) ;
2005-11-02 20:26:49 +03:00
for ( i = 0 ; i < spec - > num_mixers ; i + + )
snd_hda_resume_ctls ( codec , spec - > mixers [ i ] ) ;
if ( spec - > multiout . dig_out_nid )
snd_hda_resume_spdif_out ( codec ) ;
if ( spec - > dig_in_nid )
snd_hda_resume_spdif_in ( codec ) ;
2005-04-14 15:35:51 +04:00
return 0 ;
}
# endif
static struct hda_codec_ops ad198x_patch_ops = {
. build_controls = ad198x_build_controls ,
. build_pcms = ad198x_build_pcms ,
. init = ad198x_init ,
. free = ad198x_free ,
# ifdef CONFIG_PM
. resume = ad198x_resume ,
# endif
} ;
/*
* AD1986A specific
*/
2005-04-17 02:20:36 +04:00
# define AD1986A_SPDIF_OUT 0x02
# define AD1986A_FRONT_DAC 0x03
# define AD1986A_SURR_DAC 0x04
# define AD1986A_CLFE_DAC 0x05
# define AD1986A_ADC 0x06
static hda_nid_t ad1986a_dac_nids [ 3 ] = {
AD1986A_FRONT_DAC , AD1986A_SURR_DAC , AD1986A_CLFE_DAC
} ;
2005-11-02 20:26:49 +03:00
static hda_nid_t ad1986a_adc_nids [ 1 ] = { AD1986A_ADC } ;
2005-04-17 02:20:36 +04:00
static struct hda_input_mux ad1986a_capture_source = {
. num_items = 7 ,
. items = {
{ " Mic " , 0x0 } ,
{ " CD " , 0x1 } ,
{ " Aux " , 0x3 } ,
{ " Line " , 0x4 } ,
{ " Mix " , 0x5 } ,
{ " Mono " , 0x6 } ,
{ " Phone " , 0x7 } ,
} ,
} ;
/*
* PCM control
*
* bind volumes / mutes of 3 DACs as a single PCM control for simplicity
*/
# define ad1986a_pcm_amp_vol_info snd_hda_mixer_amp_volume_info
2005-11-17 16:57:47 +03:00
static int ad1986a_pcm_amp_vol_get ( struct snd_kcontrol * kcontrol , struct snd_ctl_elem_value * ucontrol )
2005-04-17 02:20:36 +04:00
{
struct hda_codec * codec = snd_kcontrol_chip ( kcontrol ) ;
2005-04-14 15:35:51 +04:00
struct ad198x_spec * ad = codec - > spec ;
2005-04-17 02:20:36 +04:00
down ( & ad - > amp_mutex ) ;
snd_hda_mixer_amp_volume_get ( kcontrol , ucontrol ) ;
up ( & ad - > amp_mutex ) ;
return 0 ;
}
2005-11-17 16:57:47 +03:00
static int ad1986a_pcm_amp_vol_put ( struct snd_kcontrol * kcontrol , struct snd_ctl_elem_value * ucontrol )
2005-04-17 02:20:36 +04:00
{
struct hda_codec * codec = snd_kcontrol_chip ( kcontrol ) ;
2005-04-14 15:35:51 +04:00
struct ad198x_spec * ad = codec - > spec ;
2005-04-17 02:20:36 +04:00
int i , change = 0 ;
down ( & ad - > amp_mutex ) ;
for ( i = 0 ; i < ARRAY_SIZE ( ad1986a_dac_nids ) ; i + + ) {
kcontrol - > private_value = HDA_COMPOSE_AMP_VAL ( ad1986a_dac_nids [ i ] , 3 , 0 , HDA_OUTPUT ) ;
change | = snd_hda_mixer_amp_volume_put ( kcontrol , ucontrol ) ;
}
kcontrol - > private_value = HDA_COMPOSE_AMP_VAL ( AD1986A_FRONT_DAC , 3 , 0 , HDA_OUTPUT ) ;
up ( & ad - > amp_mutex ) ;
return change ;
}
2005-06-08 16:48:19 +04:00
# define ad1986a_pcm_amp_sw_info snd_hda_mixer_amp_switch_info
2005-04-17 02:20:36 +04:00
2005-11-17 16:57:47 +03:00
static int ad1986a_pcm_amp_sw_get ( struct snd_kcontrol * kcontrol , struct snd_ctl_elem_value * ucontrol )
2005-04-17 02:20:36 +04:00
{
struct hda_codec * codec = snd_kcontrol_chip ( kcontrol ) ;
2005-04-14 15:35:51 +04:00
struct ad198x_spec * ad = codec - > spec ;
2005-04-17 02:20:36 +04:00
down ( & ad - > amp_mutex ) ;
snd_hda_mixer_amp_switch_get ( kcontrol , ucontrol ) ;
up ( & ad - > amp_mutex ) ;
return 0 ;
}
2005-11-17 16:57:47 +03:00
static int ad1986a_pcm_amp_sw_put ( struct snd_kcontrol * kcontrol , struct snd_ctl_elem_value * ucontrol )
2005-04-17 02:20:36 +04:00
{
struct hda_codec * codec = snd_kcontrol_chip ( kcontrol ) ;
2005-04-14 15:35:51 +04:00
struct ad198x_spec * ad = codec - > spec ;
2005-04-17 02:20:36 +04:00
int i , change = 0 ;
down ( & ad - > amp_mutex ) ;
for ( i = 0 ; i < ARRAY_SIZE ( ad1986a_dac_nids ) ; i + + ) {
kcontrol - > private_value = HDA_COMPOSE_AMP_VAL ( ad1986a_dac_nids [ i ] , 3 , 0 , HDA_OUTPUT ) ;
change | = snd_hda_mixer_amp_switch_put ( kcontrol , ucontrol ) ;
}
kcontrol - > private_value = HDA_COMPOSE_AMP_VAL ( AD1986A_FRONT_DAC , 3 , 0 , HDA_OUTPUT ) ;
up ( & ad - > amp_mutex ) ;
return change ;
}
/*
* mixers
*/
2005-11-17 16:57:47 +03:00
static struct snd_kcontrol_new ad1986a_mixers [ ] = {
2005-04-17 02:20:36 +04:00
{
. iface = SNDRV_CTL_ELEM_IFACE_MIXER ,
. name = " PCM Playback Volume " ,
. info = ad1986a_pcm_amp_vol_info ,
. get = ad1986a_pcm_amp_vol_get ,
. put = ad1986a_pcm_amp_vol_put ,
. private_value = HDA_COMPOSE_AMP_VAL ( AD1986A_FRONT_DAC , 3 , 0 , HDA_OUTPUT )
} ,
{
. iface = SNDRV_CTL_ELEM_IFACE_MIXER ,
. name = " PCM Playback Switch " ,
. info = ad1986a_pcm_amp_sw_info ,
. get = ad1986a_pcm_amp_sw_get ,
. put = ad1986a_pcm_amp_sw_put ,
. private_value = HDA_COMPOSE_AMP_VAL ( AD1986A_FRONT_DAC , 3 , 0 , HDA_OUTPUT )
} ,
HDA_CODEC_VOLUME ( " Front Playback Volume " , 0x1b , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_MUTE ( " Front Playback Switch " , 0x1b , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_VOLUME ( " Surround Playback Volume " , 0x1c , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_MUTE ( " Surround Playback Switch " , 0x1c , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_VOLUME_MONO ( " Center Playback Volume " , 0x1d , 1 , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_VOLUME_MONO ( " LFE Playback Volume " , 0x1d , 2 , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_MUTE_MONO ( " Center Playback Switch " , 0x1d , 1 , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_MUTE_MONO ( " LFE Playback Switch " , 0x1d , 2 , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_VOLUME ( " Headphone Playback Volume " , 0x1a , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_MUTE ( " Headphone Playback Switch " , 0x1a , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_VOLUME ( " CD Playback Volume " , 0x15 , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_MUTE ( " CD Playback Switch " , 0x15 , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_VOLUME ( " Line Playback Volume " , 0x17 , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_MUTE ( " Line Playback Switch " , 0x17 , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_VOLUME ( " Aux Playback Volume " , 0x16 , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_MUTE ( " Aux Playback Switch " , 0x16 , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_VOLUME ( " Mic Playback Volume " , 0x13 , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_MUTE ( " Mic Playback Switch " , 0x13 , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_VOLUME ( " PC Speaker Playback Volume " , 0x18 , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_MUTE ( " PC Speaker Playback Switch " , 0x18 , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_VOLUME ( " Mono Playback Volume " , 0x1e , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_MUTE ( " Mono Playback Switch " , 0x1e , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_VOLUME ( " Capture Volume " , 0x12 , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_MUTE ( " Capture Switch " , 0x12 , 0x0 , HDA_OUTPUT ) ,
{
. iface = SNDRV_CTL_ELEM_IFACE_MIXER ,
. name = " Capture Source " ,
2005-04-14 15:35:51 +04:00
. info = ad198x_mux_enum_info ,
. get = ad198x_mux_enum_get ,
. put = ad198x_mux_enum_put ,
2005-04-17 02:20:36 +04:00
} ,
HDA_CODEC_MUTE ( " Stereo Downmix Switch " , 0x09 , 0x0 , HDA_OUTPUT ) ,
{ } /* end */
} ;
/*
* initialization verbs
*/
static struct hda_verb ad1986a_init_verbs [ ] = {
/* Front, Surround, CLFE DAC; mute as default */
{ 0x03 , AC_VERB_SET_AMP_GAIN_MUTE , 0xb080 } ,
{ 0x04 , AC_VERB_SET_AMP_GAIN_MUTE , 0xb080 } ,
{ 0x05 , AC_VERB_SET_AMP_GAIN_MUTE , 0xb080 } ,
/* Downmix - off */
{ 0x09 , AC_VERB_SET_AMP_GAIN_MUTE , 0xb080 } ,
/* HP, Line-Out, Surround, CLFE selectors */
{ 0x0a , AC_VERB_SET_CONNECT_SEL , 0x0 } ,
{ 0x0b , AC_VERB_SET_CONNECT_SEL , 0x0 } ,
{ 0x0c , AC_VERB_SET_CONNECT_SEL , 0x0 } ,
{ 0x0d , AC_VERB_SET_CONNECT_SEL , 0x0 } ,
/* Mono selector */
{ 0x0e , AC_VERB_SET_CONNECT_SEL , 0x0 } ,
/* Mic selector: Mic 1/2 pin */
{ 0x0f , AC_VERB_SET_CONNECT_SEL , 0x0 } ,
/* Line-in selector: Line-in */
{ 0x10 , AC_VERB_SET_CONNECT_SEL , 0x0 } ,
/* Mic 1/2 swap */
{ 0x11 , AC_VERB_SET_CONNECT_SEL , 0x0 } ,
/* Record selector: mic */
{ 0x12 , AC_VERB_SET_CONNECT_SEL , 0x0 } ,
/* Mic, Phone, CD, Aux, Line-In amp; mute as default */
{ 0x13 , AC_VERB_SET_AMP_GAIN_MUTE , 0xb080 } ,
{ 0x14 , AC_VERB_SET_AMP_GAIN_MUTE , 0xb080 } ,
{ 0x15 , AC_VERB_SET_AMP_GAIN_MUTE , 0xb080 } ,
{ 0x16 , AC_VERB_SET_AMP_GAIN_MUTE , 0xb080 } ,
{ 0x17 , AC_VERB_SET_AMP_GAIN_MUTE , 0xb080 } ,
/* PC beep */
{ 0x18 , AC_VERB_SET_CONNECT_SEL , 0x0 } ,
/* HP, Line-Out, Surround, CLFE, Mono pins; mute as default */
{ 0x1a , AC_VERB_SET_AMP_GAIN_MUTE , 0xb080 } ,
{ 0x1b , AC_VERB_SET_AMP_GAIN_MUTE , 0xb080 } ,
{ 0x1c , AC_VERB_SET_AMP_GAIN_MUTE , 0xb080 } ,
{ 0x1d , AC_VERB_SET_AMP_GAIN_MUTE , 0xb080 } ,
{ 0x1e , AC_VERB_SET_AMP_GAIN_MUTE , 0xb080 } ,
2005-04-14 15:35:51 +04:00
/* HP Pin */
{ 0x1a , AC_VERB_SET_PIN_WIDGET_CONTROL , 0xc0 } ,
/* Front, Surround, CLFE Pins */
{ 0x1b , AC_VERB_SET_PIN_WIDGET_CONTROL , 0x40 } ,
{ 0x1c , AC_VERB_SET_PIN_WIDGET_CONTROL , 0x40 } ,
{ 0x1d , AC_VERB_SET_PIN_WIDGET_CONTROL , 0x40 } ,
/* Mono Pin */
{ 0x1e , AC_VERB_SET_PIN_WIDGET_CONTROL , 0x40 } ,
/* Mic Pin */
{ 0x1f , AC_VERB_SET_PIN_WIDGET_CONTROL , 0x24 } ,
/* Line, Aux, CD, Beep-In Pin */
{ 0x20 , AC_VERB_SET_PIN_WIDGET_CONTROL , 0x20 } ,
{ 0x21 , AC_VERB_SET_PIN_WIDGET_CONTROL , 0x20 } ,
{ 0x22 , AC_VERB_SET_PIN_WIDGET_CONTROL , 0x20 } ,
{ 0x23 , AC_VERB_SET_PIN_WIDGET_CONTROL , 0x20 } ,
{ 0x24 , AC_VERB_SET_PIN_WIDGET_CONTROL , 0x20 } ,
2005-04-17 02:20:36 +04:00
{ } /* end */
} ;
2005-04-14 15:35:51 +04:00
static int patch_ad1986a ( struct hda_codec * codec )
2005-04-17 02:20:36 +04:00
{
2005-04-14 15:35:51 +04:00
struct ad198x_spec * spec ;
2005-04-17 02:20:36 +04:00
[ALSA] Replace with kzalloc() - pci stuff
AD1889 driver,ATIIXP driver,ATIIXP-modem driver,AZT3328 driver
BT87x driver,CMIPCI driver,CS4281 driver,ENS1370/1+ driver
ES1938 driver,ES1968 driver,FM801 driver,Intel8x0 driver
Intel8x0-modem driver,Maestro3 driver,SonicVibes driver,VIA82xx driver
VIA82xx-modem driver,AC97 Codec,AK4531 codec,au88x0 driver
CA0106 driver,CS46xx driver,EMU10K1/EMU10K2 driver,HDA Codec driver
HDA generic driver,HDA Intel driver,ICE1712 driver,ICE1724 driver
KORG1212 driver,MIXART driver,NM256 driver,Trident driver,YMFPCI driver
Replace kcalloc(1,..) with kzalloc().
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2005-09-09 16:21:46 +04:00
spec = kzalloc ( sizeof ( * spec ) , GFP_KERNEL ) ;
2005-04-14 15:35:51 +04:00
if ( spec = = NULL )
return - ENOMEM ;
init_MUTEX ( & spec - > amp_mutex ) ;
codec - > spec = spec ;
spec - > multiout . max_channels = 6 ;
spec - > multiout . num_dacs = ARRAY_SIZE ( ad1986a_dac_nids ) ;
spec - > multiout . dac_nids = ad1986a_dac_nids ;
spec - > multiout . dig_out_nid = AD1986A_SPDIF_OUT ;
2005-11-02 20:26:49 +03:00
spec - > num_adc_nids = 1 ;
spec - > adc_nids = ad1986a_adc_nids ;
2005-04-14 15:35:51 +04:00
spec - > input_mux = & ad1986a_capture_source ;
2005-11-02 20:26:49 +03:00
spec - > num_mixers = 1 ;
spec - > mixers [ 0 ] = ad1986a_mixers ;
spec - > num_init_verbs = 1 ;
spec - > init_verbs [ 0 ] = ad1986a_init_verbs ;
2005-04-14 15:35:51 +04:00
codec - > patch_ops = ad198x_patch_ops ;
2005-04-17 02:20:36 +04:00
return 0 ;
}
/*
2005-04-14 15:35:51 +04:00
* AD1983 specific
2005-04-17 02:20:36 +04:00
*/
2005-04-14 15:35:51 +04:00
# define AD1983_SPDIF_OUT 0x02
# define AD1983_DAC 0x03
# define AD1983_ADC 0x04
2005-04-17 02:20:36 +04:00
2005-04-14 15:35:51 +04:00
static hda_nid_t ad1983_dac_nids [ 1 ] = { AD1983_DAC } ;
2005-11-02 20:26:49 +03:00
static hda_nid_t ad1983_adc_nids [ 1 ] = { AD1983_ADC } ;
2005-04-14 15:35:51 +04:00
static struct hda_input_mux ad1983_capture_source = {
. num_items = 4 ,
. items = {
{ " Mic " , 0x0 } ,
{ " Line " , 0x1 } ,
{ " Mix " , 0x2 } ,
{ " Mix Mono " , 0x3 } ,
} ,
} ;
2005-04-17 02:20:36 +04:00
/*
2005-04-14 15:35:51 +04:00
* SPDIF playback route
2005-04-17 02:20:36 +04:00
*/
2005-11-17 16:57:47 +03:00
static int ad1983_spdif_route_info ( struct snd_kcontrol * kcontrol , struct snd_ctl_elem_info * uinfo )
2005-04-17 02:20:36 +04:00
{
2005-04-14 15:35:51 +04:00
static char * texts [ ] = { " PCM " , " ADC " } ;
uinfo - > type = SNDRV_CTL_ELEM_TYPE_ENUMERATED ;
uinfo - > count = 1 ;
uinfo - > value . enumerated . items = 2 ;
if ( uinfo - > value . enumerated . item > 1 )
uinfo - > value . enumerated . item = 1 ;
strcpy ( uinfo - > value . enumerated . name , texts [ uinfo - > value . enumerated . item ] ) ;
return 0 ;
2005-04-17 02:20:36 +04:00
}
2005-11-17 16:57:47 +03:00
static int ad1983_spdif_route_get ( struct snd_kcontrol * kcontrol , struct snd_ctl_elem_value * ucontrol )
2005-04-17 02:20:36 +04:00
{
2005-04-14 15:35:51 +04:00
struct hda_codec * codec = snd_kcontrol_chip ( kcontrol ) ;
struct ad198x_spec * spec = codec - > spec ;
2005-04-17 02:20:36 +04:00
2005-04-14 15:35:51 +04:00
ucontrol - > value . enumerated . item [ 0 ] = spec - > spdif_route ;
2005-04-17 02:20:36 +04:00
return 0 ;
}
2005-11-17 16:57:47 +03:00
static int ad1983_spdif_route_put ( struct snd_kcontrol * kcontrol , struct snd_ctl_elem_value * ucontrol )
2005-04-17 02:20:36 +04:00
{
2005-04-14 15:35:51 +04:00
struct hda_codec * codec = snd_kcontrol_chip ( kcontrol ) ;
struct ad198x_spec * spec = codec - > spec ;
if ( spec - > spdif_route ! = ucontrol - > value . enumerated . item [ 0 ] ) {
spec - > spdif_route = ucontrol - > value . enumerated . item [ 0 ] ;
snd_hda_codec_write ( codec , spec - > multiout . dig_out_nid , 0 ,
AC_VERB_SET_CONNECT_SEL , spec - > spdif_route ) ;
return 1 ;
}
2005-04-17 02:20:36 +04:00
return 0 ;
}
2005-11-17 16:57:47 +03:00
static struct snd_kcontrol_new ad1983_mixers [ ] = {
2005-04-14 15:35:51 +04:00
HDA_CODEC_VOLUME ( " Front Playback Volume " , 0x05 , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_MUTE ( " Front Playback Switch " , 0x05 , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_VOLUME ( " Headphone Playback Volume " , 0x06 , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_MUTE ( " Headphone Playback Switch " , 0x06 , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_VOLUME_MONO ( " Mono Playback Volume " , 0x07 , 1 , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_MUTE_MONO ( " Mono Playback Switch " , 0x07 , 1 , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_VOLUME ( " PCM Playback Volume " , 0x11 , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_MUTE ( " PCM Playback Switch " , 0x11 , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_VOLUME ( " Mic Playback Volume " , 0x12 , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_MUTE ( " Mic Playback Switch " , 0x12 , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_VOLUME ( " Line Playback Volume " , 0x13 , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_MUTE ( " Line Playback Switch " , 0x13 , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_VOLUME_MONO ( " PC Speaker Playback Volume " , 0x10 , 1 , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_MUTE_MONO ( " PC Speaker Playback Switch " , 0x10 , 1 , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_VOLUME ( " Mic Boost " , 0x0c , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_VOLUME ( " Capture Volume " , 0x15 , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_MUTE ( " Capture Switch " , 0x15 , 0x0 , HDA_OUTPUT ) ,
{
. iface = SNDRV_CTL_ELEM_IFACE_MIXER ,
. name = " Capture Source " ,
. info = ad198x_mux_enum_info ,
. get = ad198x_mux_enum_get ,
. put = ad198x_mux_enum_put ,
2005-04-17 02:20:36 +04:00
} ,
2005-04-14 15:35:51 +04:00
{
. iface = SNDRV_CTL_ELEM_IFACE_MIXER ,
2005-08-03 15:40:08 +04:00
. name = SNDRV_CTL_NAME_IEC958 ( " " , PLAYBACK , NONE ) " Route " ,
2005-04-14 15:35:51 +04:00
. info = ad1983_spdif_route_info ,
. get = ad1983_spdif_route_get ,
. put = ad1983_spdif_route_put ,
2005-04-17 02:20:36 +04:00
} ,
2005-04-14 15:35:51 +04:00
{ } /* end */
2005-04-17 02:20:36 +04:00
} ;
2005-04-14 15:35:51 +04:00
static struct hda_verb ad1983_init_verbs [ ] = {
/* Front, HP, Mono; mute as default */
{ 0x05 , AC_VERB_SET_AMP_GAIN_MUTE , 0xb080 } ,
{ 0x06 , AC_VERB_SET_AMP_GAIN_MUTE , 0xb080 } ,
{ 0x07 , AC_VERB_SET_AMP_GAIN_MUTE , 0xb080 } ,
/* Beep, PCM, Mic, Line-In: mute */
{ 0x10 , AC_VERB_SET_AMP_GAIN_MUTE , 0xb080 } ,
{ 0x11 , AC_VERB_SET_AMP_GAIN_MUTE , 0xb080 } ,
{ 0x12 , AC_VERB_SET_AMP_GAIN_MUTE , 0xb080 } ,
{ 0x13 , AC_VERB_SET_AMP_GAIN_MUTE , 0xb080 } ,
/* Front, HP selectors; from Mix */
{ 0x05 , AC_VERB_SET_CONNECT_SEL , 0x01 } ,
{ 0x06 , AC_VERB_SET_CONNECT_SEL , 0x01 } ,
/* Mono selector; from Mix */
{ 0x0b , AC_VERB_SET_CONNECT_SEL , 0x03 } ,
/* Mic selector; Mic */
{ 0x0c , AC_VERB_SET_CONNECT_SEL , 0x0 } ,
/* Line-in selector: Line-in */
{ 0x0d , AC_VERB_SET_CONNECT_SEL , 0x0 } ,
/* Mic boost: 0dB */
{ 0x0c , AC_VERB_SET_AMP_GAIN_MUTE , 0xb000 } ,
/* Record selector: mic */
{ 0x15 , AC_VERB_SET_CONNECT_SEL , 0x0 } ,
{ 0x15 , AC_VERB_SET_AMP_GAIN_MUTE , 0xb080 } ,
/* SPDIF route: PCM */
{ 0x02 , AC_VERB_SET_CONNECT_SEL , 0x0 } ,
/* Front Pin */
{ 0x05 , AC_VERB_SET_PIN_WIDGET_CONTROL , 0x40 } ,
/* HP Pin */
{ 0x06 , AC_VERB_SET_PIN_WIDGET_CONTROL , 0xc0 } ,
/* Mono Pin */
{ 0x07 , AC_VERB_SET_PIN_WIDGET_CONTROL , 0x40 } ,
/* Mic Pin */
{ 0x08 , AC_VERB_SET_PIN_WIDGET_CONTROL , 0x24 } ,
/* Line Pin */
{ 0x09 , AC_VERB_SET_PIN_WIDGET_CONTROL , 0x20 } ,
{ } /* end */
2005-04-17 02:20:36 +04:00
} ;
2005-11-02 20:26:49 +03:00
2005-04-14 15:35:51 +04:00
static int patch_ad1983 ( struct hda_codec * codec )
2005-04-17 02:20:36 +04:00
{
2005-04-14 15:35:51 +04:00
struct ad198x_spec * spec ;
2005-04-17 02:20:36 +04:00
[ALSA] Replace with kzalloc() - pci stuff
AD1889 driver,ATIIXP driver,ATIIXP-modem driver,AZT3328 driver
BT87x driver,CMIPCI driver,CS4281 driver,ENS1370/1+ driver
ES1938 driver,ES1968 driver,FM801 driver,Intel8x0 driver
Intel8x0-modem driver,Maestro3 driver,SonicVibes driver,VIA82xx driver
VIA82xx-modem driver,AC97 Codec,AK4531 codec,au88x0 driver
CA0106 driver,CS46xx driver,EMU10K1/EMU10K2 driver,HDA Codec driver
HDA generic driver,HDA Intel driver,ICE1712 driver,ICE1724 driver
KORG1212 driver,MIXART driver,NM256 driver,Trident driver,YMFPCI driver
Replace kcalloc(1,..) with kzalloc().
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2005-09-09 16:21:46 +04:00
spec = kzalloc ( sizeof ( * spec ) , GFP_KERNEL ) ;
2005-04-14 15:35:51 +04:00
if ( spec = = NULL )
return - ENOMEM ;
2005-04-17 02:20:36 +04:00
2005-04-14 15:35:51 +04:00
init_MUTEX ( & spec - > amp_mutex ) ;
codec - > spec = spec ;
spec - > multiout . max_channels = 2 ;
spec - > multiout . num_dacs = ARRAY_SIZE ( ad1983_dac_nids ) ;
spec - > multiout . dac_nids = ad1983_dac_nids ;
spec - > multiout . dig_out_nid = AD1983_SPDIF_OUT ;
2005-11-02 20:26:49 +03:00
spec - > num_adc_nids = 1 ;
spec - > adc_nids = ad1983_adc_nids ;
2005-04-14 15:35:51 +04:00
spec - > input_mux = & ad1983_capture_source ;
2005-11-02 20:26:49 +03:00
spec - > num_mixers = 1 ;
spec - > mixers [ 0 ] = ad1983_mixers ;
spec - > num_init_verbs = 1 ;
spec - > init_verbs [ 0 ] = ad1983_init_verbs ;
2005-04-14 15:35:51 +04:00
spec - > spdif_route = 0 ;
2005-04-17 02:20:36 +04:00
2005-04-14 15:35:51 +04:00
codec - > patch_ops = ad198x_patch_ops ;
2005-04-17 02:20:36 +04:00
return 0 ;
}
2005-04-14 15:35:51 +04:00
/*
* AD1981 HD specific
*/
2005-04-17 02:20:36 +04:00
2005-04-14 15:35:51 +04:00
# define AD1981_SPDIF_OUT 0x02
# define AD1981_DAC 0x03
# define AD1981_ADC 0x04
static hda_nid_t ad1981_dac_nids [ 1 ] = { AD1981_DAC } ;
2005-11-02 20:26:49 +03:00
static hda_nid_t ad1981_adc_nids [ 1 ] = { AD1981_ADC } ;
2005-04-14 15:35:51 +04:00
/* 0x0c, 0x09, 0x0e, 0x0f, 0x19, 0x05, 0x18, 0x17 */
static struct hda_input_mux ad1981_capture_source = {
. num_items = 7 ,
. items = {
{ " Front Mic " , 0x0 } ,
{ " Line " , 0x1 } ,
{ " Mix " , 0x2 } ,
{ " Mix Mono " , 0x3 } ,
{ " CD " , 0x4 } ,
{ " Mic " , 0x6 } ,
{ " Aux " , 0x7 } ,
} ,
2005-04-17 02:20:36 +04:00
} ;
2005-11-17 16:57:47 +03:00
static struct snd_kcontrol_new ad1981_mixers [ ] = {
2005-04-14 15:35:51 +04:00
HDA_CODEC_VOLUME ( " Front Playback Volume " , 0x05 , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_MUTE ( " Front Playback Switch " , 0x05 , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_VOLUME ( " Headphone Playback Volume " , 0x06 , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_MUTE ( " Headphone Playback Switch " , 0x06 , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_VOLUME_MONO ( " Mono Playback Volume " , 0x07 , 1 , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_MUTE_MONO ( " Mono Playback Switch " , 0x07 , 1 , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_VOLUME ( " PCM Playback Volume " , 0x11 , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_MUTE ( " PCM Playback Switch " , 0x11 , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_VOLUME ( " Front Mic Playback Volume " , 0x12 , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_MUTE ( " Front Mic Playback Switch " , 0x12 , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_VOLUME ( " Line Playback Volume " , 0x13 , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_MUTE ( " Line Playback Switch " , 0x13 , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_VOLUME ( " Aux Playback Volume " , 0x1b , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_MUTE ( " Aux Playback Switch " , 0x1b , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_VOLUME ( " Mic Playback Volume " , 0x1c , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_MUTE ( " Mic Playback Switch " , 0x1c , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_VOLUME ( " CD Playback Volume " , 0x1d , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_MUTE ( " CD Playback Switch " , 0x1d , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_VOLUME_MONO ( " PC Speaker Playback Volume " , 0x0d , 1 , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_MUTE_MONO ( " PC Speaker Playback Switch " , 0x0d , 1 , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_VOLUME ( " Front Mic Boost " , 0x08 , 0x0 , HDA_INPUT ) ,
HDA_CODEC_VOLUME ( " Mic Boost " , 0x18 , 0x0 , HDA_INPUT ) ,
HDA_CODEC_VOLUME ( " Capture Volume " , 0x15 , 0x0 , HDA_OUTPUT ) ,
HDA_CODEC_MUTE ( " Capture Switch " , 0x15 , 0x0 , HDA_OUTPUT ) ,
{
. iface = SNDRV_CTL_ELEM_IFACE_MIXER ,
. name = " Capture Source " ,
. info = ad198x_mux_enum_info ,
. get = ad198x_mux_enum_get ,
. put = ad198x_mux_enum_put ,
} ,
/* identical with AD1983 */
{
. iface = SNDRV_CTL_ELEM_IFACE_MIXER ,
2005-08-03 15:40:08 +04:00
. name = SNDRV_CTL_NAME_IEC958 ( " " , PLAYBACK , NONE ) " Route " ,
2005-04-14 15:35:51 +04:00
. info = ad1983_spdif_route_info ,
. get = ad1983_spdif_route_get ,
. put = ad1983_spdif_route_put ,
} ,
{ } /* end */
} ;
static struct hda_verb ad1981_init_verbs [ ] = {
/* Front, HP, Mono; mute as default */
{ 0x05 , AC_VERB_SET_AMP_GAIN_MUTE , 0xb080 } ,
{ 0x06 , AC_VERB_SET_AMP_GAIN_MUTE , 0xb080 } ,
{ 0x07 , AC_VERB_SET_AMP_GAIN_MUTE , 0xb080 } ,
/* Beep, PCM, Front Mic, Line, Rear Mic, Aux, CD-In: mute */
{ 0x0d , AC_VERB_SET_AMP_GAIN_MUTE , 0xb080 } ,
{ 0x11 , AC_VERB_SET_AMP_GAIN_MUTE , 0xb080 } ,
{ 0x12 , AC_VERB_SET_AMP_GAIN_MUTE , 0xb080 } ,
{ 0x13 , AC_VERB_SET_AMP_GAIN_MUTE , 0xb080 } ,
{ 0x1b , AC_VERB_SET_AMP_GAIN_MUTE , 0xb080 } ,
{ 0x1c , AC_VERB_SET_AMP_GAIN_MUTE , 0xb080 } ,
{ 0x1d , AC_VERB_SET_AMP_GAIN_MUTE , 0xb080 } ,
/* Front, HP selectors; from Mix */
{ 0x05 , AC_VERB_SET_CONNECT_SEL , 0x01 } ,
{ 0x06 , AC_VERB_SET_CONNECT_SEL , 0x01 } ,
/* Mono selector; from Mix */
{ 0x0b , AC_VERB_SET_CONNECT_SEL , 0x03 } ,
/* Mic Mixer; select Front Mic */
{ 0x1e , AC_VERB_SET_AMP_GAIN_MUTE , 0xb000 } ,
{ 0x1f , AC_VERB_SET_AMP_GAIN_MUTE , 0xb080 } ,
/* Mic boost: 0dB */
{ 0x08 , AC_VERB_SET_AMP_GAIN_MUTE , 0xb000 } ,
{ 0x18 , AC_VERB_SET_AMP_GAIN_MUTE , 0xb000 } ,
/* Record selector: Front mic */
{ 0x15 , AC_VERB_SET_CONNECT_SEL , 0x0 } ,
{ 0x15 , AC_VERB_SET_AMP_GAIN_MUTE , 0xb080 } ,
/* SPDIF route: PCM */
{ 0x02 , AC_VERB_SET_CONNECT_SEL , 0x0 } ,
/* Front Pin */
{ 0x05 , AC_VERB_SET_PIN_WIDGET_CONTROL , 0x40 } ,
/* HP Pin */
{ 0x06 , AC_VERB_SET_PIN_WIDGET_CONTROL , 0xc0 } ,
/* Mono Pin */
{ 0x07 , AC_VERB_SET_PIN_WIDGET_CONTROL , 0x40 } ,
/* Front & Rear Mic Pins */
{ 0x08 , AC_VERB_SET_PIN_WIDGET_CONTROL , 0x24 } ,
{ 0x18 , AC_VERB_SET_PIN_WIDGET_CONTROL , 0x24 } ,
/* Line Pin */
{ 0x09 , AC_VERB_SET_PIN_WIDGET_CONTROL , 0x20 } ,
/* Digital Beep */
{ 0x0d , AC_VERB_SET_CONNECT_SEL , 0x00 } ,
/* Line-Out as Input: disabled */
{ 0x1a , AC_VERB_SET_AMP_GAIN_MUTE , 0xb080 } ,
{ } /* end */
} ;
static int patch_ad1981 ( struct hda_codec * codec )
2005-04-17 02:20:36 +04:00
{
2005-04-14 15:35:51 +04:00
struct ad198x_spec * spec ;
2005-04-17 02:20:36 +04:00
[ALSA] Replace with kzalloc() - pci stuff
AD1889 driver,ATIIXP driver,ATIIXP-modem driver,AZT3328 driver
BT87x driver,CMIPCI driver,CS4281 driver,ENS1370/1+ driver
ES1938 driver,ES1968 driver,FM801 driver,Intel8x0 driver
Intel8x0-modem driver,Maestro3 driver,SonicVibes driver,VIA82xx driver
VIA82xx-modem driver,AC97 Codec,AK4531 codec,au88x0 driver
CA0106 driver,CS46xx driver,EMU10K1/EMU10K2 driver,HDA Codec driver
HDA generic driver,HDA Intel driver,ICE1712 driver,ICE1724 driver
KORG1212 driver,MIXART driver,NM256 driver,Trident driver,YMFPCI driver
Replace kcalloc(1,..) with kzalloc().
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2005-09-09 16:21:46 +04:00
spec = kzalloc ( sizeof ( * spec ) , GFP_KERNEL ) ;
2005-04-17 02:20:36 +04:00
if ( spec = = NULL )
return - ENOMEM ;
init_MUTEX ( & spec - > amp_mutex ) ;
codec - > spec = spec ;
2005-04-14 15:35:51 +04:00
spec - > multiout . max_channels = 2 ;
spec - > multiout . num_dacs = ARRAY_SIZE ( ad1981_dac_nids ) ;
spec - > multiout . dac_nids = ad1981_dac_nids ;
spec - > multiout . dig_out_nid = AD1981_SPDIF_OUT ;
2005-11-02 20:26:49 +03:00
spec - > num_adc_nids = 1 ;
spec - > adc_nids = ad1981_adc_nids ;
2005-04-14 15:35:51 +04:00
spec - > input_mux = & ad1981_capture_source ;
2005-11-02 20:26:49 +03:00
spec - > num_mixers = 1 ;
spec - > mixers [ 0 ] = ad1981_mixers ;
spec - > num_init_verbs = 1 ;
spec - > init_verbs [ 0 ] = ad1981_init_verbs ;
2005-04-14 15:35:51 +04:00
spec - > spdif_route = 0 ;
2005-04-17 02:20:36 +04:00
2005-04-14 15:35:51 +04:00
codec - > patch_ops = ad198x_patch_ops ;
2005-04-17 02:20:36 +04:00
return 0 ;
}
2005-04-14 15:35:51 +04:00
2005-04-17 02:20:36 +04:00
/*
* patch entries
*/
struct hda_codec_preset snd_hda_preset_analog [ ] = {
2005-04-14 15:35:51 +04:00
{ . id = 0x11d41981 , . name = " AD1981 " , . patch = patch_ad1981 } ,
{ . id = 0x11d41983 , . name = " AD1983 " , . patch = patch_ad1983 } ,
2005-04-17 02:20:36 +04:00
{ . id = 0x11d41986 , . name = " AD1986A " , . patch = patch_ad1986a } ,
{ } /* terminator */
} ;