diff options
Diffstat (limited to 'sound/pci/hda/patch_conexant.c')
-rw-r--r-- | sound/pci/hda/patch_conexant.c | 43 |
1 files changed, 37 insertions, 6 deletions
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index a09c03c3f62b..c578c28f368e 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -29,6 +29,7 @@ | |||
29 | 29 | ||
30 | #include "hda_codec.h" | 30 | #include "hda_codec.h" |
31 | #include "hda_local.h" | 31 | #include "hda_local.h" |
32 | #include "hda_beep.h" | ||
32 | 33 | ||
33 | #define CXT_PIN_DIR_IN 0x00 | 34 | #define CXT_PIN_DIR_IN 0x00 |
34 | #define CXT_PIN_DIR_OUT 0x01 | 35 | #define CXT_PIN_DIR_OUT 0x01 |
@@ -111,6 +112,7 @@ struct conexant_spec { | |||
111 | unsigned int dell_automute; | 112 | unsigned int dell_automute; |
112 | unsigned int port_d_mode; | 113 | unsigned int port_d_mode; |
113 | unsigned char ext_mic_bias; | 114 | unsigned char ext_mic_bias; |
115 | unsigned int dell_vostro; | ||
114 | }; | 116 | }; |
115 | 117 | ||
116 | static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo, | 118 | static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo, |
@@ -476,6 +478,7 @@ static void conexant_free(struct hda_codec *codec) | |||
476 | snd_array_free(&spec->jacks); | 478 | snd_array_free(&spec->jacks); |
477 | } | 479 | } |
478 | #endif | 480 | #endif |
481 | snd_hda_detach_beep_device(codec); | ||
479 | kfree(codec->spec); | 482 | kfree(codec->spec); |
480 | } | 483 | } |
481 | 484 | ||
@@ -2109,9 +2112,12 @@ static int cxt5066_mic_boost_mux_enum_get(struct snd_kcontrol *kcontrol, | |||
2109 | { | 2112 | { |
2110 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 2113 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
2111 | int val; | 2114 | int val; |
2115 | hda_nid_t nid = kcontrol->private_value & 0xff; | ||
2116 | int inout = (kcontrol->private_value & 0x100) ? | ||
2117 | AC_AMP_GET_INPUT : AC_AMP_GET_OUTPUT; | ||
2112 | 2118 | ||
2113 | val = snd_hda_codec_read(codec, 0x17, 0, | 2119 | val = snd_hda_codec_read(codec, nid, 0, |
2114 | AC_VERB_GET_AMP_GAIN_MUTE, AC_AMP_GET_OUTPUT); | 2120 | AC_VERB_GET_AMP_GAIN_MUTE, inout); |
2115 | 2121 | ||
2116 | ucontrol->value.enumerated.item[0] = val & AC_AMP_GAIN; | 2122 | ucontrol->value.enumerated.item[0] = val & AC_AMP_GAIN; |
2117 | return 0; | 2123 | return 0; |
@@ -2123,6 +2129,9 @@ static int cxt5066_mic_boost_mux_enum_put(struct snd_kcontrol *kcontrol, | |||
2123 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 2129 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
2124 | const struct hda_input_mux *imux = &cxt5066_analog_mic_boost; | 2130 | const struct hda_input_mux *imux = &cxt5066_analog_mic_boost; |
2125 | unsigned int idx; | 2131 | unsigned int idx; |
2132 | hda_nid_t nid = kcontrol->private_value & 0xff; | ||
2133 | int inout = (kcontrol->private_value & 0x100) ? | ||
2134 | AC_AMP_SET_INPUT : AC_AMP_SET_OUTPUT; | ||
2126 | 2135 | ||
2127 | if (!imux->num_items) | 2136 | if (!imux->num_items) |
2128 | return 0; | 2137 | return 0; |
@@ -2130,9 +2139,9 @@ static int cxt5066_mic_boost_mux_enum_put(struct snd_kcontrol *kcontrol, | |||
2130 | if (idx >= imux->num_items) | 2139 | if (idx >= imux->num_items) |
2131 | idx = imux->num_items - 1; | 2140 | idx = imux->num_items - 1; |
2132 | 2141 | ||
2133 | snd_hda_codec_write_cache(codec, 0x17, 0, | 2142 | snd_hda_codec_write_cache(codec, nid, 0, |
2134 | AC_VERB_SET_AMP_GAIN_MUTE, | 2143 | AC_VERB_SET_AMP_GAIN_MUTE, |
2135 | AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_OUTPUT | | 2144 | AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | inout | |
2136 | imux->items[idx].index); | 2145 | imux->items[idx].index); |
2137 | 2146 | ||
2138 | return 1; | 2147 | return 1; |
@@ -2201,10 +2210,11 @@ static struct snd_kcontrol_new cxt5066_mixers[] = { | |||
2201 | 2210 | ||
2202 | { | 2211 | { |
2203 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 2212 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
2204 | .name = "Analog Mic Boost Capture Enum", | 2213 | .name = "Ext Mic Boost Capture Enum", |
2205 | .info = cxt5066_mic_boost_mux_enum_info, | 2214 | .info = cxt5066_mic_boost_mux_enum_info, |
2206 | .get = cxt5066_mic_boost_mux_enum_get, | 2215 | .get = cxt5066_mic_boost_mux_enum_get, |
2207 | .put = cxt5066_mic_boost_mux_enum_put, | 2216 | .put = cxt5066_mic_boost_mux_enum_put, |
2217 | .private_value = 0x17, | ||
2208 | }, | 2218 | }, |
2209 | 2219 | ||
2210 | HDA_BIND_VOL("Capture Volume", &cxt5066_bind_capture_vol_others), | 2220 | HDA_BIND_VOL("Capture Volume", &cxt5066_bind_capture_vol_others), |
@@ -2212,6 +2222,19 @@ static struct snd_kcontrol_new cxt5066_mixers[] = { | |||
2212 | {} | 2222 | {} |
2213 | }; | 2223 | }; |
2214 | 2224 | ||
2225 | static struct snd_kcontrol_new cxt5066_vostro_mixers[] = { | ||
2226 | { | ||
2227 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
2228 | .name = "Int Mic Boost Capture Enum", | ||
2229 | .info = cxt5066_mic_boost_mux_enum_info, | ||
2230 | .get = cxt5066_mic_boost_mux_enum_get, | ||
2231 | .put = cxt5066_mic_boost_mux_enum_put, | ||
2232 | .private_value = 0x23 | 0x100, | ||
2233 | }, | ||
2234 | HDA_CODEC_VOLUME_MONO("Beep Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT), | ||
2235 | {} | ||
2236 | }; | ||
2237 | |||
2215 | static struct hda_verb cxt5066_init_verbs[] = { | 2238 | static struct hda_verb cxt5066_init_verbs[] = { |
2216 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */ | 2239 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */ |
2217 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */ | 2240 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */ |
@@ -2397,11 +2420,16 @@ static struct hda_verb cxt5066_init_verbs_portd_lo[] = { | |||
2397 | /* initialize jack-sensing, too */ | 2420 | /* initialize jack-sensing, too */ |
2398 | static int cxt5066_init(struct hda_codec *codec) | 2421 | static int cxt5066_init(struct hda_codec *codec) |
2399 | { | 2422 | { |
2423 | struct conexant_spec *spec = codec->spec; | ||
2424 | |||
2400 | snd_printdd("CXT5066: init\n"); | 2425 | snd_printdd("CXT5066: init\n"); |
2401 | conexant_init(codec); | 2426 | conexant_init(codec); |
2402 | if (codec->patch_ops.unsol_event) { | 2427 | if (codec->patch_ops.unsol_event) { |
2403 | cxt5066_hp_automute(codec); | 2428 | cxt5066_hp_automute(codec); |
2404 | cxt5066_automic(codec); | 2429 | if (spec->dell_vostro) |
2430 | cxt5066_vostro_automic(codec); | ||
2431 | else | ||
2432 | cxt5066_automic(codec); | ||
2405 | } | 2433 | } |
2406 | return 0; | 2434 | return 0; |
2407 | } | 2435 | } |
@@ -2500,7 +2528,10 @@ static int patch_cxt5066(struct hda_codec *codec) | |||
2500 | spec->init_verbs[0] = cxt5066_init_verbs_vostro; | 2528 | spec->init_verbs[0] = cxt5066_init_verbs_vostro; |
2501 | spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc; | 2529 | spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc; |
2502 | spec->mixers[spec->num_mixers++] = cxt5066_mixers; | 2530 | spec->mixers[spec->num_mixers++] = cxt5066_mixers; |
2531 | spec->mixers[spec->num_mixers++] = cxt5066_vostro_mixers; | ||
2503 | spec->port_d_mode = 0; | 2532 | spec->port_d_mode = 0; |
2533 | spec->dell_vostro = 1; | ||
2534 | snd_hda_attach_beep_device(codec, 0x13); | ||
2504 | 2535 | ||
2505 | /* no S/PDIF out */ | 2536 | /* no S/PDIF out */ |
2506 | spec->multiout.dig_out_nid = 0; | 2537 | spec->multiout.dig_out_nid = 0; |