diff options
author | Grant Likely <grant.likely@secretlab.ca> | 2010-01-28 16:38:25 -0500 |
---|---|---|
committer | Grant Likely <grant.likely@secretlab.ca> | 2010-01-28 16:38:25 -0500 |
commit | 0ada0a73120c28cc432bcdbac061781465c2f48f (patch) | |
tree | d17cadd4ea47e25d9e48e7d409a39c84268fbd27 /sound/pci/hda/patch_conexant.c | |
parent | 6016a363f6b56b46b24655bcfc0499b715851cf3 (diff) | |
parent | 92dcffb916d309aa01778bf8963a6932e4014d07 (diff) |
Merge commit 'v2.6.33-rc5' into secretlab/test-devicetree
Diffstat (limited to 'sound/pci/hda/patch_conexant.c')
-rw-r--r-- | sound/pci/hda/patch_conexant.c | 232 |
1 files changed, 187 insertions, 45 deletions
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 905859d4f4df..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, |
@@ -397,9 +399,7 @@ static void conexant_report_jack(struct hda_codec *codec, hda_nid_t nid) | |||
397 | for (i = 0; i < spec->jacks.used; i++) { | 399 | for (i = 0; i < spec->jacks.used; i++) { |
398 | if (jacks->nid == nid) { | 400 | if (jacks->nid == nid) { |
399 | unsigned int present; | 401 | unsigned int present; |
400 | present = snd_hda_codec_read(codec, nid, 0, | 402 | present = snd_hda_jack_detect(codec, nid); |
401 | AC_VERB_GET_PIN_SENSE, 0) & | ||
402 | AC_PINSENSE_PRESENCE; | ||
403 | 403 | ||
404 | present = (present) ? jacks->type : 0 ; | 404 | present = (present) ? jacks->type : 0 ; |
405 | 405 | ||
@@ -478,6 +478,7 @@ static void conexant_free(struct hda_codec *codec) | |||
478 | snd_array_free(&spec->jacks); | 478 | snd_array_free(&spec->jacks); |
479 | } | 479 | } |
480 | #endif | 480 | #endif |
481 | snd_hda_detach_beep_device(codec); | ||
481 | kfree(codec->spec); | 482 | kfree(codec->spec); |
482 | } | 483 | } |
483 | 484 | ||
@@ -750,8 +751,7 @@ static void cxt5045_hp_automic(struct hda_codec *codec) | |||
750 | }; | 751 | }; |
751 | unsigned int present; | 752 | unsigned int present; |
752 | 753 | ||
753 | present = snd_hda_codec_read(codec, 0x12, 0, | 754 | present = snd_hda_jack_detect(codec, 0x12); |
754 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
755 | if (present) | 755 | if (present) |
756 | snd_hda_sequence_write(codec, mic_jack_on); | 756 | snd_hda_sequence_write(codec, mic_jack_on); |
757 | else | 757 | else |
@@ -765,8 +765,7 @@ static void cxt5045_hp_automute(struct hda_codec *codec) | |||
765 | struct conexant_spec *spec = codec->spec; | 765 | struct conexant_spec *spec = codec->spec; |
766 | unsigned int bits; | 766 | unsigned int bits; |
767 | 767 | ||
768 | spec->hp_present = snd_hda_codec_read(codec, 0x11, 0, | 768 | spec->hp_present = snd_hda_jack_detect(codec, 0x11); |
769 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
770 | 769 | ||
771 | bits = (spec->hp_present || !spec->cur_eapd) ? HDA_AMP_MUTE : 0; | 770 | bits = (spec->hp_present || !spec->cur_eapd) ? HDA_AMP_MUTE : 0; |
772 | snd_hda_codec_amp_stereo(codec, 0x10, HDA_OUTPUT, 0, | 771 | snd_hda_codec_amp_stereo(codec, 0x10, HDA_OUTPUT, 0, |
@@ -1175,9 +1174,10 @@ static int patch_cxt5045(struct hda_codec *codec) | |||
1175 | 1174 | ||
1176 | switch (codec->subsystem_id >> 16) { | 1175 | switch (codec->subsystem_id >> 16) { |
1177 | case 0x103c: | 1176 | case 0x103c: |
1178 | /* HP laptop has a really bad sound over 0dB on NID 0x17. | 1177 | case 0x1734: |
1179 | * Fix max PCM level to 0 dB | 1178 | /* HP & Fujitsu-Siemens laptops have really bad sound over 0dB |
1180 | * (originall it has 0x2b steps with 0dB offset 0x14) | 1179 | * on NID 0x17. Fix max PCM level to 0 dB |
1180 | * (originally it has 0x2b steps with 0dB offset 0x14) | ||
1181 | */ | 1181 | */ |
1182 | snd_hda_override_amp_caps(codec, 0x17, HDA_INPUT, | 1182 | snd_hda_override_amp_caps(codec, 0x17, HDA_INPUT, |
1183 | (0x14 << AC_AMPCAP_OFFSET_SHIFT) | | 1183 | (0x14 << AC_AMPCAP_OFFSET_SHIFT) | |
@@ -1243,8 +1243,7 @@ static void cxt5047_hp_automute(struct hda_codec *codec) | |||
1243 | struct conexant_spec *spec = codec->spec; | 1243 | struct conexant_spec *spec = codec->spec; |
1244 | unsigned int bits; | 1244 | unsigned int bits; |
1245 | 1245 | ||
1246 | spec->hp_present = snd_hda_codec_read(codec, 0x13, 0, | 1246 | spec->hp_present = snd_hda_jack_detect(codec, 0x13); |
1247 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
1248 | 1247 | ||
1249 | bits = (spec->hp_present || !spec->cur_eapd) ? HDA_AMP_MUTE : 0; | 1248 | bits = (spec->hp_present || !spec->cur_eapd) ? HDA_AMP_MUTE : 0; |
1250 | /* See the note in cxt5047_hp_master_sw_put */ | 1249 | /* See the note in cxt5047_hp_master_sw_put */ |
@@ -1267,8 +1266,7 @@ static void cxt5047_hp_automic(struct hda_codec *codec) | |||
1267 | }; | 1266 | }; |
1268 | unsigned int present; | 1267 | unsigned int present; |
1269 | 1268 | ||
1270 | present = snd_hda_codec_read(codec, 0x15, 0, | 1269 | present = snd_hda_jack_detect(codec, 0x15); |
1271 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
1272 | if (present) | 1270 | if (present) |
1273 | snd_hda_sequence_write(codec, mic_jack_on); | 1271 | snd_hda_sequence_write(codec, mic_jack_on); |
1274 | else | 1272 | else |
@@ -1415,16 +1413,7 @@ static struct snd_kcontrol_new cxt5047_test_mixer[] = { | |||
1415 | .get = conexant_mux_enum_get, | 1413 | .get = conexant_mux_enum_get, |
1416 | .put = conexant_mux_enum_put, | 1414 | .put = conexant_mux_enum_put, |
1417 | }, | 1415 | }, |
1418 | HDA_CODEC_VOLUME("Input-1 Volume", 0x1a, 0x0, HDA_INPUT), | 1416 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x1a, 0x0, HDA_OUTPUT), |
1419 | HDA_CODEC_MUTE("Input-1 Switch", 0x1a, 0x0, HDA_INPUT), | ||
1420 | HDA_CODEC_VOLUME("Input-2 Volume", 0x1a, 0x1, HDA_INPUT), | ||
1421 | HDA_CODEC_MUTE("Input-2 Switch", 0x1a, 0x1, HDA_INPUT), | ||
1422 | HDA_CODEC_VOLUME("Input-3 Volume", 0x1a, 0x2, HDA_INPUT), | ||
1423 | HDA_CODEC_MUTE("Input-3 Switch", 0x1a, 0x2, HDA_INPUT), | ||
1424 | HDA_CODEC_VOLUME("Input-4 Volume", 0x1a, 0x3, HDA_INPUT), | ||
1425 | HDA_CODEC_MUTE("Input-4 Switch", 0x1a, 0x3, HDA_INPUT), | ||
1426 | HDA_CODEC_VOLUME("Input-5 Volume", 0x1a, 0x4, HDA_INPUT), | ||
1427 | HDA_CODEC_MUTE("Input-5 Switch", 0x1a, 0x4, HDA_INPUT), | ||
1428 | 1417 | ||
1429 | { } /* end */ | 1418 | { } /* end */ |
1430 | }; | 1419 | }; |
@@ -1621,9 +1610,7 @@ static void cxt5051_portb_automic(struct hda_codec *codec) | |||
1621 | 1610 | ||
1622 | if (spec->no_auto_mic) | 1611 | if (spec->no_auto_mic) |
1623 | return; | 1612 | return; |
1624 | present = snd_hda_codec_read(codec, 0x17, 0, | 1613 | present = snd_hda_jack_detect(codec, 0x17); |
1625 | AC_VERB_GET_PIN_SENSE, 0) & | ||
1626 | AC_PINSENSE_PRESENCE; | ||
1627 | snd_hda_codec_write(codec, 0x14, 0, | 1614 | snd_hda_codec_write(codec, 0x14, 0, |
1628 | AC_VERB_SET_CONNECT_SEL, | 1615 | AC_VERB_SET_CONNECT_SEL, |
1629 | present ? 0x01 : 0x00); | 1616 | present ? 0x01 : 0x00); |
@@ -1638,9 +1625,7 @@ static void cxt5051_portc_automic(struct hda_codec *codec) | |||
1638 | 1625 | ||
1639 | if (spec->no_auto_mic) | 1626 | if (spec->no_auto_mic) |
1640 | return; | 1627 | return; |
1641 | present = snd_hda_codec_read(codec, 0x18, 0, | 1628 | present = snd_hda_jack_detect(codec, 0x18); |
1642 | AC_VERB_GET_PIN_SENSE, 0) & | ||
1643 | AC_PINSENSE_PRESENCE; | ||
1644 | if (present) | 1629 | if (present) |
1645 | spec->cur_adc_idx = 1; | 1630 | spec->cur_adc_idx = 1; |
1646 | else | 1631 | else |
@@ -1661,9 +1646,7 @@ static void cxt5051_hp_automute(struct hda_codec *codec) | |||
1661 | { | 1646 | { |
1662 | struct conexant_spec *spec = codec->spec; | 1647 | struct conexant_spec *spec = codec->spec; |
1663 | 1648 | ||
1664 | spec->hp_present = snd_hda_codec_read(codec, 0x16, 0, | 1649 | spec->hp_present = snd_hda_jack_detect(codec, 0x16); |
1665 | AC_VERB_GET_PIN_SENSE, 0) & | ||
1666 | AC_PINSENSE_PRESENCE; | ||
1667 | cxt5051_update_speaker(codec); | 1650 | cxt5051_update_speaker(codec); |
1668 | } | 1651 | } |
1669 | 1652 | ||
@@ -2011,8 +1994,47 @@ static void cxt5066_automic(struct hda_codec *codec) | |||
2011 | }; | 1994 | }; |
2012 | unsigned int present; | 1995 | unsigned int present; |
2013 | 1996 | ||
2014 | present = snd_hda_codec_read(codec, 0x1a, 0, | 1997 | present = snd_hda_jack_detect(codec, 0x1a); |
2015 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | 1998 | if (present) { |
1999 | snd_printdd("CXT5066: external microphone detected\n"); | ||
2000 | snd_hda_sequence_write(codec, ext_mic_present); | ||
2001 | } else { | ||
2002 | snd_printdd("CXT5066: external microphone absent\n"); | ||
2003 | snd_hda_sequence_write(codec, ext_mic_absent); | ||
2004 | } | ||
2005 | } | ||
2006 | |||
2007 | /* toggle input of built-in digital mic and mic jack appropriately */ | ||
2008 | static void cxt5066_vostro_automic(struct hda_codec *codec) | ||
2009 | { | ||
2010 | struct conexant_spec *spec = codec->spec; | ||
2011 | unsigned int present; | ||
2012 | |||
2013 | struct hda_verb ext_mic_present[] = { | ||
2014 | /* enable external mic, port B */ | ||
2015 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, spec->ext_mic_bias}, | ||
2016 | |||
2017 | /* switch to external mic input */ | ||
2018 | {0x17, AC_VERB_SET_CONNECT_SEL, 0}, | ||
2019 | {0x14, AC_VERB_SET_CONNECT_SEL, 0}, | ||
2020 | |||
2021 | /* disable internal digital mic */ | ||
2022 | {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
2023 | {} | ||
2024 | }; | ||
2025 | static struct hda_verb ext_mic_absent[] = { | ||
2026 | /* enable internal mic, port C */ | ||
2027 | {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
2028 | |||
2029 | /* switch to internal mic input */ | ||
2030 | {0x14, AC_VERB_SET_CONNECT_SEL, 2}, | ||
2031 | |||
2032 | /* disable external mic, port B */ | ||
2033 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
2034 | {} | ||
2035 | }; | ||
2036 | |||
2037 | present = snd_hda_jack_detect(codec, 0x1a); | ||
2016 | if (present) { | 2038 | if (present) { |
2017 | snd_printdd("CXT5066: external microphone detected\n"); | 2039 | snd_printdd("CXT5066: external microphone detected\n"); |
2018 | snd_hda_sequence_write(codec, ext_mic_present); | 2040 | snd_hda_sequence_write(codec, ext_mic_present); |
@@ -2029,12 +2051,10 @@ static void cxt5066_hp_automute(struct hda_codec *codec) | |||
2029 | unsigned int portA, portD; | 2051 | unsigned int portA, portD; |
2030 | 2052 | ||
2031 | /* Port A */ | 2053 | /* Port A */ |
2032 | portA = snd_hda_codec_read(codec, 0x19, 0, AC_VERB_GET_PIN_SENSE, 0) | 2054 | portA = snd_hda_jack_detect(codec, 0x19); |
2033 | & AC_PINSENSE_PRESENCE; | ||
2034 | 2055 | ||
2035 | /* Port D */ | 2056 | /* Port D */ |
2036 | portD = (snd_hda_codec_read(codec, 0x1c, 0, AC_VERB_GET_PIN_SENSE, 0) | 2057 | portD = snd_hda_jack_detect(codec, 0x1c); |
2037 | & AC_PINSENSE_PRESENCE) << 1; | ||
2038 | 2058 | ||
2039 | spec->hp_present = !!(portA | portD); | 2059 | spec->hp_present = !!(portA | portD); |
2040 | snd_printdd("CXT5066: hp automute portA=%x portD=%x present=%d\n", | 2060 | snd_printdd("CXT5066: hp automute portA=%x portD=%x present=%d\n", |
@@ -2056,6 +2076,20 @@ static void cxt5066_unsol_event(struct hda_codec *codec, unsigned int res) | |||
2056 | } | 2076 | } |
2057 | } | 2077 | } |
2058 | 2078 | ||
2079 | /* unsolicited event for jack sensing */ | ||
2080 | static void cxt5066_vostro_event(struct hda_codec *codec, unsigned int res) | ||
2081 | { | ||
2082 | snd_printdd("CXT5066_vostro: unsol event %x (%x)\n", res, res >> 26); | ||
2083 | switch (res >> 26) { | ||
2084 | case CONEXANT_HP_EVENT: | ||
2085 | cxt5066_hp_automute(codec); | ||
2086 | break; | ||
2087 | case CONEXANT_MIC_EVENT: | ||
2088 | cxt5066_vostro_automic(codec); | ||
2089 | break; | ||
2090 | } | ||
2091 | } | ||
2092 | |||
2059 | static const struct hda_input_mux cxt5066_analog_mic_boost = { | 2093 | static const struct hda_input_mux cxt5066_analog_mic_boost = { |
2060 | .num_items = 5, | 2094 | .num_items = 5, |
2061 | .items = { | 2095 | .items = { |
@@ -2078,9 +2112,12 @@ static int cxt5066_mic_boost_mux_enum_get(struct snd_kcontrol *kcontrol, | |||
2078 | { | 2112 | { |
2079 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 2113 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
2080 | 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; | ||
2081 | 2118 | ||
2082 | val = snd_hda_codec_read(codec, 0x17, 0, | 2119 | val = snd_hda_codec_read(codec, nid, 0, |
2083 | AC_VERB_GET_AMP_GAIN_MUTE, AC_AMP_GET_OUTPUT); | 2120 | AC_VERB_GET_AMP_GAIN_MUTE, inout); |
2084 | 2121 | ||
2085 | ucontrol->value.enumerated.item[0] = val & AC_AMP_GAIN; | 2122 | ucontrol->value.enumerated.item[0] = val & AC_AMP_GAIN; |
2086 | return 0; | 2123 | return 0; |
@@ -2092,6 +2129,9 @@ static int cxt5066_mic_boost_mux_enum_put(struct snd_kcontrol *kcontrol, | |||
2092 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 2129 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
2093 | const struct hda_input_mux *imux = &cxt5066_analog_mic_boost; | 2130 | const struct hda_input_mux *imux = &cxt5066_analog_mic_boost; |
2094 | 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; | ||
2095 | 2135 | ||
2096 | if (!imux->num_items) | 2136 | if (!imux->num_items) |
2097 | return 0; | 2137 | return 0; |
@@ -2099,9 +2139,9 @@ static int cxt5066_mic_boost_mux_enum_put(struct snd_kcontrol *kcontrol, | |||
2099 | if (idx >= imux->num_items) | 2139 | if (idx >= imux->num_items) |
2100 | idx = imux->num_items - 1; | 2140 | idx = imux->num_items - 1; |
2101 | 2141 | ||
2102 | snd_hda_codec_write_cache(codec, 0x17, 0, | 2142 | snd_hda_codec_write_cache(codec, nid, 0, |
2103 | AC_VERB_SET_AMP_GAIN_MUTE, | 2143 | AC_VERB_SET_AMP_GAIN_MUTE, |
2104 | AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_OUTPUT | | 2144 | AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | inout | |
2105 | imux->items[idx].index); | 2145 | imux->items[idx].index); |
2106 | 2146 | ||
2107 | return 1; | 2147 | return 1; |
@@ -2170,10 +2210,11 @@ static struct snd_kcontrol_new cxt5066_mixers[] = { | |||
2170 | 2210 | ||
2171 | { | 2211 | { |
2172 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 2212 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
2173 | .name = "Analog Mic Boost Capture Enum", | 2213 | .name = "Ext Mic Boost Capture Enum", |
2174 | .info = cxt5066_mic_boost_mux_enum_info, | 2214 | .info = cxt5066_mic_boost_mux_enum_info, |
2175 | .get = cxt5066_mic_boost_mux_enum_get, | 2215 | .get = cxt5066_mic_boost_mux_enum_get, |
2176 | .put = cxt5066_mic_boost_mux_enum_put, | 2216 | .put = cxt5066_mic_boost_mux_enum_put, |
2217 | .private_value = 0x17, | ||
2177 | }, | 2218 | }, |
2178 | 2219 | ||
2179 | HDA_BIND_VOL("Capture Volume", &cxt5066_bind_capture_vol_others), | 2220 | HDA_BIND_VOL("Capture Volume", &cxt5066_bind_capture_vol_others), |
@@ -2181,6 +2222,19 @@ static struct snd_kcontrol_new cxt5066_mixers[] = { | |||
2181 | {} | 2222 | {} |
2182 | }; | 2223 | }; |
2183 | 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 | |||
2184 | static struct hda_verb cxt5066_init_verbs[] = { | 2238 | static struct hda_verb cxt5066_init_verbs[] = { |
2185 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */ | 2239 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */ |
2186 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */ | 2240 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */ |
@@ -2297,6 +2351,67 @@ static struct hda_verb cxt5066_init_verbs_olpc[] = { | |||
2297 | { } /* end */ | 2351 | { } /* end */ |
2298 | }; | 2352 | }; |
2299 | 2353 | ||
2354 | static struct hda_verb cxt5066_init_verbs_vostro[] = { | ||
2355 | /* Port A: headphones */ | ||
2356 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
2357 | {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ | ||
2358 | |||
2359 | /* Port B: external microphone */ | ||
2360 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
2361 | |||
2362 | /* Port C: unused */ | ||
2363 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
2364 | |||
2365 | /* Port D: unused */ | ||
2366 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
2367 | |||
2368 | /* Port E: unused, but has primary EAPD */ | ||
2369 | {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
2370 | {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ | ||
2371 | |||
2372 | /* Port F: unused */ | ||
2373 | {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
2374 | |||
2375 | /* Port G: internal speakers */ | ||
2376 | {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
2377 | {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ | ||
2378 | |||
2379 | /* DAC1 */ | ||
2380 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
2381 | |||
2382 | /* DAC2: unused */ | ||
2383 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
2384 | |||
2385 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
2386 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
2387 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
2388 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
2389 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
2390 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
2391 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
2392 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
2393 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
2394 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
2395 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
2396 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
2397 | |||
2398 | /* Digital microphone port */ | ||
2399 | {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
2400 | |||
2401 | /* Audio input selectors */ | ||
2402 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x3}, | ||
2403 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | ||
2404 | |||
2405 | /* Disable SPDIF */ | ||
2406 | {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
2407 | {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
2408 | |||
2409 | /* enable unsolicited events for Port A and B */ | ||
2410 | {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, | ||
2411 | {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT}, | ||
2412 | { } /* end */ | ||
2413 | }; | ||
2414 | |||
2300 | static struct hda_verb cxt5066_init_verbs_portd_lo[] = { | 2415 | static struct hda_verb cxt5066_init_verbs_portd_lo[] = { |
2301 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 2416 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
2302 | { } /* end */ | 2417 | { } /* end */ |
@@ -2305,11 +2420,16 @@ static struct hda_verb cxt5066_init_verbs_portd_lo[] = { | |||
2305 | /* initialize jack-sensing, too */ | 2420 | /* initialize jack-sensing, too */ |
2306 | static int cxt5066_init(struct hda_codec *codec) | 2421 | static int cxt5066_init(struct hda_codec *codec) |
2307 | { | 2422 | { |
2423 | struct conexant_spec *spec = codec->spec; | ||
2424 | |||
2308 | snd_printdd("CXT5066: init\n"); | 2425 | snd_printdd("CXT5066: init\n"); |
2309 | conexant_init(codec); | 2426 | conexant_init(codec); |
2310 | if (codec->patch_ops.unsol_event) { | 2427 | if (codec->patch_ops.unsol_event) { |
2311 | cxt5066_hp_automute(codec); | 2428 | cxt5066_hp_automute(codec); |
2312 | cxt5066_automic(codec); | 2429 | if (spec->dell_vostro) |
2430 | cxt5066_vostro_automic(codec); | ||
2431 | else | ||
2432 | cxt5066_automic(codec); | ||
2313 | } | 2433 | } |
2314 | return 0; | 2434 | return 0; |
2315 | } | 2435 | } |
@@ -2318,6 +2438,7 @@ enum { | |||
2318 | CXT5066_LAPTOP, /* Laptops w/ EAPD support */ | 2438 | CXT5066_LAPTOP, /* Laptops w/ EAPD support */ |
2319 | CXT5066_DELL_LAPTOP, /* Dell Laptop */ | 2439 | CXT5066_DELL_LAPTOP, /* Dell Laptop */ |
2320 | CXT5066_OLPC_XO_1_5, /* OLPC XO 1.5 */ | 2440 | CXT5066_OLPC_XO_1_5, /* OLPC XO 1.5 */ |
2441 | CXT5066_DELL_VOSTO, /* Dell Vostro 1015i */ | ||
2321 | CXT5066_MODELS | 2442 | CXT5066_MODELS |
2322 | }; | 2443 | }; |
2323 | 2444 | ||
@@ -2325,6 +2446,7 @@ static const char *cxt5066_models[CXT5066_MODELS] = { | |||
2325 | [CXT5066_LAPTOP] = "laptop", | 2446 | [CXT5066_LAPTOP] = "laptop", |
2326 | [CXT5066_DELL_LAPTOP] = "dell-laptop", | 2447 | [CXT5066_DELL_LAPTOP] = "dell-laptop", |
2327 | [CXT5066_OLPC_XO_1_5] = "olpc-xo-1_5", | 2448 | [CXT5066_OLPC_XO_1_5] = "olpc-xo-1_5", |
2449 | [CXT5066_DELL_VOSTO] = "dell-vostro" | ||
2328 | }; | 2450 | }; |
2329 | 2451 | ||
2330 | static struct snd_pci_quirk cxt5066_cfg_tbl[] = { | 2452 | static struct snd_pci_quirk cxt5066_cfg_tbl[] = { |
@@ -2333,6 +2455,7 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = { | |||
2333 | SND_PCI_QUIRK(0x1028, 0x02f5, "Dell", | 2455 | SND_PCI_QUIRK(0x1028, 0x02f5, "Dell", |
2334 | CXT5066_DELL_LAPTOP), | 2456 | CXT5066_DELL_LAPTOP), |
2335 | SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5), | 2457 | SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5), |
2458 | SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTO), | ||
2336 | {} | 2459 | {} |
2337 | }; | 2460 | }; |
2338 | 2461 | ||
@@ -2400,6 +2523,22 @@ static int patch_cxt5066(struct hda_codec *codec) | |||
2400 | /* input source automatically selected */ | 2523 | /* input source automatically selected */ |
2401 | spec->input_mux = NULL; | 2524 | spec->input_mux = NULL; |
2402 | break; | 2525 | break; |
2526 | case CXT5066_DELL_VOSTO: | ||
2527 | codec->patch_ops.unsol_event = cxt5066_vostro_event; | ||
2528 | spec->init_verbs[0] = cxt5066_init_verbs_vostro; | ||
2529 | spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc; | ||
2530 | spec->mixers[spec->num_mixers++] = cxt5066_mixers; | ||
2531 | spec->mixers[spec->num_mixers++] = cxt5066_vostro_mixers; | ||
2532 | spec->port_d_mode = 0; | ||
2533 | spec->dell_vostro = 1; | ||
2534 | snd_hda_attach_beep_device(codec, 0x13); | ||
2535 | |||
2536 | /* no S/PDIF out */ | ||
2537 | spec->multiout.dig_out_nid = 0; | ||
2538 | |||
2539 | /* input source automatically selected */ | ||
2540 | spec->input_mux = NULL; | ||
2541 | break; | ||
2403 | } | 2542 | } |
2404 | 2543 | ||
2405 | return 0; | 2544 | return 0; |
@@ -2417,6 +2556,8 @@ static struct hda_codec_preset snd_hda_preset_conexant[] = { | |||
2417 | .patch = patch_cxt5051 }, | 2556 | .patch = patch_cxt5051 }, |
2418 | { .id = 0x14f15066, .name = "CX20582 (Pebble)", | 2557 | { .id = 0x14f15066, .name = "CX20582 (Pebble)", |
2419 | .patch = patch_cxt5066 }, | 2558 | .patch = patch_cxt5066 }, |
2559 | { .id = 0x14f15067, .name = "CX20583 (Pebble HSF)", | ||
2560 | .patch = patch_cxt5066 }, | ||
2420 | {} /* terminator */ | 2561 | {} /* terminator */ |
2421 | }; | 2562 | }; |
2422 | 2563 | ||
@@ -2424,6 +2565,7 @@ MODULE_ALIAS("snd-hda-codec-id:14f15045"); | |||
2424 | MODULE_ALIAS("snd-hda-codec-id:14f15047"); | 2565 | MODULE_ALIAS("snd-hda-codec-id:14f15047"); |
2425 | MODULE_ALIAS("snd-hda-codec-id:14f15051"); | 2566 | MODULE_ALIAS("snd-hda-codec-id:14f15051"); |
2426 | MODULE_ALIAS("snd-hda-codec-id:14f15066"); | 2567 | MODULE_ALIAS("snd-hda-codec-id:14f15066"); |
2568 | MODULE_ALIAS("snd-hda-codec-id:14f15067"); | ||
2427 | 2569 | ||
2428 | MODULE_LICENSE("GPL"); | 2570 | MODULE_LICENSE("GPL"); |
2429 | MODULE_DESCRIPTION("Conexant HD-audio codec"); | 2571 | MODULE_DESCRIPTION("Conexant HD-audio codec"); |