diff options
Diffstat (limited to 'sound/pci/hda/patch_conexant.c')
-rw-r--r-- | sound/pci/hda/patch_conexant.c | 169 |
1 files changed, 161 insertions, 8 deletions
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 61682e1d09da..e863649d31f5 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -115,6 +115,7 @@ struct conexant_spec { | |||
115 | unsigned int port_d_mode; | 115 | unsigned int port_d_mode; |
116 | unsigned int dell_vostro:1; | 116 | unsigned int dell_vostro:1; |
117 | unsigned int ideapad:1; | 117 | unsigned int ideapad:1; |
118 | unsigned int thinkpad:1; | ||
118 | 119 | ||
119 | unsigned int ext_mic_present; | 120 | unsigned int ext_mic_present; |
120 | unsigned int recording; | 121 | unsigned int recording; |
@@ -1195,10 +1196,12 @@ static int patch_cxt5045(struct hda_codec *codec) | |||
1195 | 1196 | ||
1196 | switch (codec->subsystem_id >> 16) { | 1197 | switch (codec->subsystem_id >> 16) { |
1197 | case 0x103c: | 1198 | case 0x103c: |
1199 | case 0x1631: | ||
1198 | case 0x1734: | 1200 | case 0x1734: |
1199 | /* HP & Fujitsu-Siemens laptops have really bad sound over 0dB | 1201 | case 0x17aa: |
1200 | * on NID 0x17. Fix max PCM level to 0 dB | 1202 | /* HP, Packard Bell, Fujitsu-Siemens & Lenovo laptops have |
1201 | * (originally it has 0x2b steps with 0dB offset 0x14) | 1203 | * really bad sound over 0dB on NID 0x17. Fix max PCM level to |
1204 | * 0 dB (originally it has 0x2b steps with 0dB offset 0x14) | ||
1202 | */ | 1205 | */ |
1203 | snd_hda_override_amp_caps(codec, 0x17, HDA_INPUT, | 1206 | snd_hda_override_amp_caps(codec, 0x17, HDA_INPUT, |
1204 | (0x14 << AC_AMPCAP_OFFSET_SHIFT) | | 1207 | (0x14 << AC_AMPCAP_OFFSET_SHIFT) | |
@@ -1782,6 +1785,7 @@ static struct hda_verb cxt5051_init_verbs[] = { | |||
1782 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44}, | 1785 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44}, |
1783 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44}, | 1786 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44}, |
1784 | /* SPDIF route: PCM */ | 1787 | /* SPDIF route: PCM */ |
1788 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
1785 | {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0}, | 1789 | {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0}, |
1786 | /* EAPD */ | 1790 | /* EAPD */ |
1787 | {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ | 1791 | {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ |
@@ -1838,6 +1842,7 @@ static struct hda_verb cxt5051_lenovo_x200_init_verbs[] = { | |||
1838 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44}, | 1842 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44}, |
1839 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44}, | 1843 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44}, |
1840 | /* SPDIF route: PCM */ | 1844 | /* SPDIF route: PCM */ |
1845 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* needed for W500 Advanced Mini Dock 250410 */ | ||
1841 | {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0}, | 1846 | {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0}, |
1842 | /* EAPD */ | 1847 | /* EAPD */ |
1843 | {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ | 1848 | {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ |
@@ -1909,7 +1914,7 @@ enum { | |||
1909 | CXT5051_LAPTOP, /* Laptops w/ EAPD support */ | 1914 | CXT5051_LAPTOP, /* Laptops w/ EAPD support */ |
1910 | CXT5051_HP, /* no docking */ | 1915 | CXT5051_HP, /* no docking */ |
1911 | CXT5051_HP_DV6736, /* HP without mic switch */ | 1916 | CXT5051_HP_DV6736, /* HP without mic switch */ |
1912 | CXT5051_LENOVO_X200, /* Lenovo X200 laptop */ | 1917 | CXT5051_LENOVO_X200, /* Lenovo X200 laptop, also used for Advanced Mini Dock 250410 */ |
1913 | CXT5051_F700, /* HP Compaq Presario F700 */ | 1918 | CXT5051_F700, /* HP Compaq Presario F700 */ |
1914 | CXT5051_TOSHIBA, /* Toshiba M300 & co */ | 1919 | CXT5051_TOSHIBA, /* Toshiba M300 & co */ |
1915 | CXT5051_MODELS | 1920 | CXT5051_MODELS |
@@ -2031,6 +2036,9 @@ static void cxt5066_update_speaker(struct hda_codec *codec) | |||
2031 | /* Port D (HP/LO) */ | 2036 | /* Port D (HP/LO) */ |
2032 | pinctl = ((spec->hp_present & 2) && spec->cur_eapd) | 2037 | pinctl = ((spec->hp_present & 2) && spec->cur_eapd) |
2033 | ? spec->port_d_mode : 0; | 2038 | ? spec->port_d_mode : 0; |
2039 | /* Mute if Port A is connected on Thinkpad */ | ||
2040 | if (spec->thinkpad && (spec->hp_present & 1)) | ||
2041 | pinctl = 0; | ||
2034 | snd_hda_codec_write(codec, 0x1c, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | 2042 | snd_hda_codec_write(codec, 0x1c, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, |
2035 | pinctl); | 2043 | pinctl); |
2036 | 2044 | ||
@@ -2211,6 +2219,50 @@ static void cxt5066_ideapad_automic(struct hda_codec *codec) | |||
2211 | } | 2219 | } |
2212 | } | 2220 | } |
2213 | 2221 | ||
2222 | /* toggle input of built-in digital mic and mic jack appropriately | ||
2223 | order is: external mic -> dock mic -> interal mic */ | ||
2224 | static void cxt5066_thinkpad_automic(struct hda_codec *codec) | ||
2225 | { | ||
2226 | unsigned int ext_present, dock_present; | ||
2227 | |||
2228 | static struct hda_verb ext_mic_present[] = { | ||
2229 | {0x14, AC_VERB_SET_CONNECT_SEL, 0}, | ||
2230 | {0x17, AC_VERB_SET_CONNECT_SEL, 1}, | ||
2231 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
2232 | {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
2233 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
2234 | {} | ||
2235 | }; | ||
2236 | static struct hda_verb dock_mic_present[] = { | ||
2237 | {0x14, AC_VERB_SET_CONNECT_SEL, 0}, | ||
2238 | {0x17, AC_VERB_SET_CONNECT_SEL, 0}, | ||
2239 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
2240 | {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
2241 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
2242 | {} | ||
2243 | }; | ||
2244 | static struct hda_verb ext_mic_absent[] = { | ||
2245 | {0x14, AC_VERB_SET_CONNECT_SEL, 2}, | ||
2246 | {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
2247 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
2248 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
2249 | {} | ||
2250 | }; | ||
2251 | |||
2252 | ext_present = snd_hda_jack_detect(codec, 0x1b); | ||
2253 | dock_present = snd_hda_jack_detect(codec, 0x1a); | ||
2254 | if (ext_present) { | ||
2255 | snd_printdd("CXT5066: external microphone detected\n"); | ||
2256 | snd_hda_sequence_write(codec, ext_mic_present); | ||
2257 | } else if (dock_present) { | ||
2258 | snd_printdd("CXT5066: dock microphone detected\n"); | ||
2259 | snd_hda_sequence_write(codec, dock_mic_present); | ||
2260 | } else { | ||
2261 | snd_printdd("CXT5066: external microphone absent\n"); | ||
2262 | snd_hda_sequence_write(codec, ext_mic_absent); | ||
2263 | } | ||
2264 | } | ||
2265 | |||
2214 | /* mute internal speaker if HP is plugged */ | 2266 | /* mute internal speaker if HP is plugged */ |
2215 | static void cxt5066_hp_automute(struct hda_codec *codec) | 2267 | static void cxt5066_hp_automute(struct hda_codec *codec) |
2216 | { | 2268 | { |
@@ -2223,7 +2275,8 @@ static void cxt5066_hp_automute(struct hda_codec *codec) | |||
2223 | /* Port D */ | 2275 | /* Port D */ |
2224 | portD = snd_hda_jack_detect(codec, 0x1c); | 2276 | portD = snd_hda_jack_detect(codec, 0x1c); |
2225 | 2277 | ||
2226 | spec->hp_present = !!(portA | portD); | 2278 | spec->hp_present = !!(portA); |
2279 | spec->hp_present |= portD ? 2 : 0; | ||
2227 | snd_printdd("CXT5066: hp automute portA=%x portD=%x present=%d\n", | 2280 | snd_printdd("CXT5066: hp automute portA=%x portD=%x present=%d\n", |
2228 | portA, portD, spec->hp_present); | 2281 | portA, portD, spec->hp_present); |
2229 | cxt5066_update_speaker(codec); | 2282 | cxt5066_update_speaker(codec); |
@@ -2274,6 +2327,20 @@ static void cxt5066_ideapad_event(struct hda_codec *codec, unsigned int res) | |||
2274 | } | 2327 | } |
2275 | } | 2328 | } |
2276 | 2329 | ||
2330 | /* unsolicited event for jack sensing */ | ||
2331 | static void cxt5066_thinkpad_event(struct hda_codec *codec, unsigned int res) | ||
2332 | { | ||
2333 | snd_printdd("CXT5066_thinkpad: unsol event %x (%x)\n", res, res >> 26); | ||
2334 | switch (res >> 26) { | ||
2335 | case CONEXANT_HP_EVENT: | ||
2336 | cxt5066_hp_automute(codec); | ||
2337 | break; | ||
2338 | case CONEXANT_MIC_EVENT: | ||
2339 | cxt5066_thinkpad_automic(codec); | ||
2340 | break; | ||
2341 | } | ||
2342 | } | ||
2343 | |||
2277 | static const struct hda_input_mux cxt5066_analog_mic_boost = { | 2344 | static const struct hda_input_mux cxt5066_analog_mic_boost = { |
2278 | .num_items = 5, | 2345 | .num_items = 5, |
2279 | .items = { | 2346 | .items = { |
@@ -2292,7 +2359,7 @@ static void cxt5066_set_mic_boost(struct hda_codec *codec) | |||
2292 | AC_VERB_SET_AMP_GAIN_MUTE, | 2359 | AC_VERB_SET_AMP_GAIN_MUTE, |
2293 | AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_OUTPUT | | 2360 | AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_OUTPUT | |
2294 | cxt5066_analog_mic_boost.items[spec->mic_boost].index); | 2361 | cxt5066_analog_mic_boost.items[spec->mic_boost].index); |
2295 | if (spec->ideapad) { | 2362 | if (spec->ideapad || spec->thinkpad) { |
2296 | /* adjust the internal mic as well...it is not through 0x17 */ | 2363 | /* adjust the internal mic as well...it is not through 0x17 */ |
2297 | snd_hda_codec_write_cache(codec, 0x23, 0, | 2364 | snd_hda_codec_write_cache(codec, 0x23, 0, |
2298 | AC_VERB_SET_AMP_GAIN_MUTE, | 2365 | AC_VERB_SET_AMP_GAIN_MUTE, |
@@ -2780,6 +2847,64 @@ static struct hda_verb cxt5066_init_verbs_ideapad[] = { | |||
2780 | { } /* end */ | 2847 | { } /* end */ |
2781 | }; | 2848 | }; |
2782 | 2849 | ||
2850 | static struct hda_verb cxt5066_init_verbs_thinkpad[] = { | ||
2851 | {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */ | ||
2852 | {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port E */ | ||
2853 | |||
2854 | /* Port G: internal speakers */ | ||
2855 | {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
2856 | {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ | ||
2857 | |||
2858 | /* Port A: HP, Amp */ | ||
2859 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
2860 | {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ | ||
2861 | |||
2862 | /* Port B: Mic Dock */ | ||
2863 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
2864 | |||
2865 | /* Port C: Mic */ | ||
2866 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
2867 | |||
2868 | /* Port D: HP Dock, Amp */ | ||
2869 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
2870 | {0x1c, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ | ||
2871 | |||
2872 | /* DAC1 */ | ||
2873 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
2874 | |||
2875 | /* Node 14 connections: 0x17 0x18 0x23 0x24 0x27 */ | ||
2876 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50}, | ||
2877 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
2878 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2) | 0x50}, | ||
2879 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
2880 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | ||
2881 | {0x14, AC_VERB_SET_CONNECT_SEL, 2}, /* default to internal mic */ | ||
2882 | |||
2883 | /* Audio input selector */ | ||
2884 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x2}, | ||
2885 | {0x17, AC_VERB_SET_CONNECT_SEL, 1}, /* route ext mic */ | ||
2886 | |||
2887 | /* SPDIF route: PCM */ | ||
2888 | {0x20, AC_VERB_SET_CONNECT_SEL, 0x0}, | ||
2889 | {0x22, AC_VERB_SET_CONNECT_SEL, 0x0}, | ||
2890 | |||
2891 | {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
2892 | {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
2893 | |||
2894 | /* internal microphone */ | ||
2895 | {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable int mic */ | ||
2896 | |||
2897 | /* EAPD */ | ||
2898 | {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ | ||
2899 | |||
2900 | /* enable unsolicited events for Port A, B, C and D */ | ||
2901 | {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, | ||
2902 | {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, | ||
2903 | {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT}, | ||
2904 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT}, | ||
2905 | { } /* end */ | ||
2906 | }; | ||
2907 | |||
2783 | static struct hda_verb cxt5066_init_verbs_portd_lo[] = { | 2908 | static struct hda_verb cxt5066_init_verbs_portd_lo[] = { |
2784 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 2909 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
2785 | { } /* end */ | 2910 | { } /* end */ |
@@ -2798,6 +2923,8 @@ static int cxt5066_init(struct hda_codec *codec) | |||
2798 | cxt5066_vostro_automic(codec); | 2923 | cxt5066_vostro_automic(codec); |
2799 | else if (spec->ideapad) | 2924 | else if (spec->ideapad) |
2800 | cxt5066_ideapad_automic(codec); | 2925 | cxt5066_ideapad_automic(codec); |
2926 | else if (spec->thinkpad) | ||
2927 | cxt5066_thinkpad_automic(codec); | ||
2801 | } | 2928 | } |
2802 | cxt5066_set_mic_boost(codec); | 2929 | cxt5066_set_mic_boost(codec); |
2803 | return 0; | 2930 | return 0; |
@@ -2819,20 +2946,22 @@ static int cxt5066_olpc_init(struct hda_codec *codec) | |||
2819 | } | 2946 | } |
2820 | 2947 | ||
2821 | enum { | 2948 | enum { |
2822 | CXT5066_LAPTOP, /* Laptops w/ EAPD support */ | 2949 | CXT5066_LAPTOP, /* Laptops w/ EAPD support */ |
2823 | CXT5066_DELL_LAPTOP, /* Dell Laptop */ | 2950 | CXT5066_DELL_LAPTOP, /* Dell Laptop */ |
2824 | CXT5066_OLPC_XO_1_5, /* OLPC XO 1.5 */ | 2951 | CXT5066_OLPC_XO_1_5, /* OLPC XO 1.5 */ |
2825 | CXT5066_DELL_VOSTO, /* Dell Vostro 1015i */ | 2952 | CXT5066_DELL_VOSTO, /* Dell Vostro 1015i */ |
2826 | CXT5066_IDEAPAD, /* Lenovo IdeaPad U150 */ | 2953 | CXT5066_IDEAPAD, /* Lenovo IdeaPad U150 */ |
2954 | CXT5066_THINKPAD, /* Lenovo ThinkPad T410s, others? */ | ||
2827 | CXT5066_MODELS | 2955 | CXT5066_MODELS |
2828 | }; | 2956 | }; |
2829 | 2957 | ||
2830 | static const char *cxt5066_models[CXT5066_MODELS] = { | 2958 | static const char *cxt5066_models[CXT5066_MODELS] = { |
2831 | [CXT5066_LAPTOP] = "laptop", | 2959 | [CXT5066_LAPTOP] = "laptop", |
2832 | [CXT5066_DELL_LAPTOP] = "dell-laptop", | 2960 | [CXT5066_DELL_LAPTOP] = "dell-laptop", |
2833 | [CXT5066_OLPC_XO_1_5] = "olpc-xo-1_5", | 2961 | [CXT5066_OLPC_XO_1_5] = "olpc-xo-1_5", |
2834 | [CXT5066_DELL_VOSTO] = "dell-vostro", | 2962 | [CXT5066_DELL_VOSTO] = "dell-vostro", |
2835 | [CXT5066_IDEAPAD] = "ideapad", | 2963 | [CXT5066_IDEAPAD] = "ideapad", |
2964 | [CXT5066_THINKPAD] = "thinkpad", | ||
2836 | }; | 2965 | }; |
2837 | 2966 | ||
2838 | static struct snd_pci_quirk cxt5066_cfg_tbl[] = { | 2967 | static struct snd_pci_quirk cxt5066_cfg_tbl[] = { |
@@ -2842,7 +2971,12 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = { | |||
2842 | CXT5066_DELL_LAPTOP), | 2971 | CXT5066_DELL_LAPTOP), |
2843 | SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5), | 2972 | SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5), |
2844 | SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTO), | 2973 | SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTO), |
2974 | SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD), | ||
2975 | SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5), | ||
2976 | SND_PCI_QUIRK(0x1179, 0xffe0, "Toshiba Satellite Pro T130-15F", CXT5066_OLPC_XO_1_5), | ||
2977 | SND_PCI_QUIRK(0x17aa, 0x21b2, "Thinkpad X100e", CXT5066_IDEAPAD), | ||
2845 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "ideapad", CXT5066_IDEAPAD), | 2978 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "ideapad", CXT5066_IDEAPAD), |
2979 | SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD), | ||
2846 | {} | 2980 | {} |
2847 | }; | 2981 | }; |
2848 | 2982 | ||
@@ -2950,6 +3084,22 @@ static int patch_cxt5066(struct hda_codec *codec) | |||
2950 | /* input source automatically selected */ | 3084 | /* input source automatically selected */ |
2951 | spec->input_mux = NULL; | 3085 | spec->input_mux = NULL; |
2952 | break; | 3086 | break; |
3087 | case CXT5066_THINKPAD: | ||
3088 | codec->patch_ops.init = cxt5066_init; | ||
3089 | codec->patch_ops.unsol_event = cxt5066_thinkpad_event; | ||
3090 | spec->mixers[spec->num_mixers++] = cxt5066_mixer_master; | ||
3091 | spec->mixers[spec->num_mixers++] = cxt5066_mixers; | ||
3092 | spec->init_verbs[0] = cxt5066_init_verbs_thinkpad; | ||
3093 | spec->thinkpad = 1; | ||
3094 | spec->port_d_mode = PIN_OUT; | ||
3095 | spec->mic_boost = 2; /* default 20dB gain */ | ||
3096 | |||
3097 | /* no S/PDIF out */ | ||
3098 | spec->multiout.dig_out_nid = 0; | ||
3099 | |||
3100 | /* input source automatically selected */ | ||
3101 | spec->input_mux = NULL; | ||
3102 | break; | ||
2953 | } | 3103 | } |
2954 | 3104 | ||
2955 | return 0; | 3105 | return 0; |
@@ -2969,6 +3119,8 @@ static struct hda_codec_preset snd_hda_preset_conexant[] = { | |||
2969 | .patch = patch_cxt5066 }, | 3119 | .patch = patch_cxt5066 }, |
2970 | { .id = 0x14f15067, .name = "CX20583 (Pebble HSF)", | 3120 | { .id = 0x14f15067, .name = "CX20583 (Pebble HSF)", |
2971 | .patch = patch_cxt5066 }, | 3121 | .patch = patch_cxt5066 }, |
3122 | { .id = 0x14f15069, .name = "CX20585", | ||
3123 | .patch = patch_cxt5066 }, | ||
2972 | {} /* terminator */ | 3124 | {} /* terminator */ |
2973 | }; | 3125 | }; |
2974 | 3126 | ||
@@ -2977,6 +3129,7 @@ MODULE_ALIAS("snd-hda-codec-id:14f15047"); | |||
2977 | MODULE_ALIAS("snd-hda-codec-id:14f15051"); | 3129 | MODULE_ALIAS("snd-hda-codec-id:14f15051"); |
2978 | MODULE_ALIAS("snd-hda-codec-id:14f15066"); | 3130 | MODULE_ALIAS("snd-hda-codec-id:14f15066"); |
2979 | MODULE_ALIAS("snd-hda-codec-id:14f15067"); | 3131 | MODULE_ALIAS("snd-hda-codec-id:14f15067"); |
3132 | MODULE_ALIAS("snd-hda-codec-id:14f15069"); | ||
2980 | 3133 | ||
2981 | MODULE_LICENSE("GPL"); | 3134 | MODULE_LICENSE("GPL"); |
2982 | MODULE_DESCRIPTION("Conexant HD-audio codec"); | 3135 | MODULE_DESCRIPTION("Conexant HD-audio codec"); |