aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_conexant.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/patch_conexant.c')
-rw-r--r--sound/pci/hda/patch_conexant.c1085
1 files changed, 808 insertions, 277 deletions
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index ad97d937d3a8..4f37477d3c71 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -39,6 +39,7 @@
39 39
40#define CONEXANT_HP_EVENT 0x37 40#define CONEXANT_HP_EVENT 0x37
41#define CONEXANT_MIC_EVENT 0x38 41#define CONEXANT_MIC_EVENT 0x38
42#define CONEXANT_LINE_EVENT 0x39
42 43
43/* Conexant 5051 specific */ 44/* Conexant 5051 specific */
44 45
@@ -55,9 +56,16 @@ struct pin_dac_pair {
55 int type; 56 int type;
56}; 57};
57 58
59struct imux_info {
60 hda_nid_t pin; /* input pin NID */
61 hda_nid_t adc; /* connected ADC NID */
62 hda_nid_t boost; /* optional boost volume NID */
63 int index; /* corresponding to autocfg.input */
64};
65
58struct conexant_spec { 66struct conexant_spec {
59 67
60 struct snd_kcontrol_new *mixers[5]; 68 const struct snd_kcontrol_new *mixers[5];
61 int num_mixers; 69 int num_mixers;
62 hda_nid_t vmaster_nid; 70 hda_nid_t vmaster_nid;
63 71
@@ -74,14 +82,17 @@ struct conexant_spec {
74 */ 82 */
75 unsigned int cur_eapd; 83 unsigned int cur_eapd;
76 unsigned int hp_present; 84 unsigned int hp_present;
85 unsigned int line_present;
77 unsigned int auto_mic; 86 unsigned int auto_mic;
78 int auto_mic_ext; /* autocfg.inputs[] index for ext mic */ 87 int auto_mic_ext; /* imux_pins[] index for ext mic */
88 int auto_mic_dock; /* imux_pins[] index for dock mic */
89 int auto_mic_int; /* imux_pins[] index for int mic */
79 unsigned int need_dac_fix; 90 unsigned int need_dac_fix;
80 hda_nid_t slave_dig_outs[2]; 91 hda_nid_t slave_dig_outs[2];
81 92
82 /* capture */ 93 /* capture */
83 unsigned int num_adc_nids; 94 unsigned int num_adc_nids;
84 hda_nid_t *adc_nids; 95 const hda_nid_t *adc_nids;
85 hda_nid_t dig_in_nid; /* digital-in NID; optional */ 96 hda_nid_t dig_in_nid; /* digital-in NID; optional */
86 97
87 unsigned int cur_adc_idx; 98 unsigned int cur_adc_idx;
@@ -89,9 +100,11 @@ struct conexant_spec {
89 unsigned int cur_adc_stream_tag; 100 unsigned int cur_adc_stream_tag;
90 unsigned int cur_adc_format; 101 unsigned int cur_adc_format;
91 102
103 const struct hda_pcm_stream *capture_stream;
104
92 /* capture source */ 105 /* capture source */
93 const struct hda_input_mux *input_mux; 106 const struct hda_input_mux *input_mux;
94 hda_nid_t *capsrc_nids; 107 const hda_nid_t *capsrc_nids;
95 unsigned int cur_mux[3]; 108 unsigned int cur_mux[3];
96 109
97 /* channel model */ 110 /* channel model */
@@ -106,12 +119,17 @@ struct conexant_spec {
106 /* dynamic controls, init_verbs and input_mux */ 119 /* dynamic controls, init_verbs and input_mux */
107 struct auto_pin_cfg autocfg; 120 struct auto_pin_cfg autocfg;
108 struct hda_input_mux private_imux; 121 struct hda_input_mux private_imux;
122 struct imux_info imux_info[HDA_MAX_NUM_INPUTS];
123 hda_nid_t private_adc_nids[HDA_MAX_NUM_INPUTS];
109 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; 124 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
110 struct pin_dac_pair dac_info[8]; 125 struct pin_dac_pair dac_info[8];
111 int dac_info_filled; 126 int dac_info_filled;
112 127
113 unsigned int port_d_mode; 128 unsigned int port_d_mode;
114 unsigned int auto_mute:1; /* used in auto-parser */ 129 unsigned int auto_mute:1; /* used in auto-parser */
130 unsigned int detect_line:1; /* Line-out detection enabled */
131 unsigned int automute_lines:1; /* automute line-out as well */
132 unsigned int automute_hp_lo:1; /* both HP and LO available */
115 unsigned int dell_automute:1; 133 unsigned int dell_automute:1;
116 unsigned int dell_vostro:1; 134 unsigned int dell_vostro:1;
117 unsigned int ideapad:1; 135 unsigned int ideapad:1;
@@ -119,6 +137,8 @@ struct conexant_spec {
119 unsigned int hp_laptop:1; 137 unsigned int hp_laptop:1;
120 unsigned int asus:1; 138 unsigned int asus:1;
121 139
140 unsigned int adc_switching:1;
141
122 unsigned int ext_mic_present; 142 unsigned int ext_mic_present;
123 unsigned int recording; 143 unsigned int recording;
124 void (*capture_prepare)(struct hda_codec *codec); 144 void (*capture_prepare)(struct hda_codec *codec);
@@ -227,7 +247,7 @@ static int conexant_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
227 247
228 248
229 249
230static struct hda_pcm_stream conexant_pcm_analog_playback = { 250static const struct hda_pcm_stream conexant_pcm_analog_playback = {
231 .substreams = 1, 251 .substreams = 1,
232 .channels_min = 2, 252 .channels_min = 2,
233 .channels_max = 2, 253 .channels_max = 2,
@@ -239,7 +259,7 @@ static struct hda_pcm_stream conexant_pcm_analog_playback = {
239 }, 259 },
240}; 260};
241 261
242static struct hda_pcm_stream conexant_pcm_analog_capture = { 262static const struct hda_pcm_stream conexant_pcm_analog_capture = {
243 .substreams = 1, 263 .substreams = 1,
244 .channels_min = 2, 264 .channels_min = 2,
245 .channels_max = 2, 265 .channels_max = 2,
@@ -251,7 +271,7 @@ static struct hda_pcm_stream conexant_pcm_analog_capture = {
251}; 271};
252 272
253 273
254static struct hda_pcm_stream conexant_pcm_digital_playback = { 274static const struct hda_pcm_stream conexant_pcm_digital_playback = {
255 .substreams = 1, 275 .substreams = 1,
256 .channels_min = 2, 276 .channels_min = 2,
257 .channels_max = 2, 277 .channels_max = 2,
@@ -263,7 +283,7 @@ static struct hda_pcm_stream conexant_pcm_digital_playback = {
263 }, 283 },
264}; 284};
265 285
266static struct hda_pcm_stream conexant_pcm_digital_capture = { 286static const struct hda_pcm_stream conexant_pcm_digital_capture = {
267 .substreams = 1, 287 .substreams = 1,
268 .channels_min = 2, 288 .channels_min = 2,
269 .channels_max = 2, 289 .channels_max = 2,
@@ -294,7 +314,7 @@ static int cx5051_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
294 return 0; 314 return 0;
295} 315}
296 316
297static struct hda_pcm_stream cx5051_pcm_analog_capture = { 317static const struct hda_pcm_stream cx5051_pcm_analog_capture = {
298 .substreams = 1, 318 .substreams = 1,
299 .channels_min = 2, 319 .channels_min = 2,
300 .channels_max = 2, 320 .channels_max = 2,
@@ -319,13 +339,19 @@ static int conexant_build_pcms(struct hda_codec *codec)
319 spec->multiout.max_channels; 339 spec->multiout.max_channels;
320 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 340 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
321 spec->multiout.dac_nids[0]; 341 spec->multiout.dac_nids[0];
322 if (codec->vendor_id == 0x14f15051) 342 if (spec->capture_stream)
323 info->stream[SNDRV_PCM_STREAM_CAPTURE] = 343 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *spec->capture_stream;
324 cx5051_pcm_analog_capture; 344 else {
325 else 345 if (codec->vendor_id == 0x14f15051)
326 info->stream[SNDRV_PCM_STREAM_CAPTURE] = 346 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
327 conexant_pcm_analog_capture; 347 cx5051_pcm_analog_capture;
328 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adc_nids; 348 else {
349 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
350 conexant_pcm_analog_capture;
351 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
352 spec->num_adc_nids;
353 }
354 }
329 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; 355 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
330 356
331 if (spec->multiout.dig_out_nid) { 357 if (spec->multiout.dig_out_nid) {
@@ -433,7 +459,7 @@ static void conexant_free(struct hda_codec *codec)
433 kfree(codec->spec); 459 kfree(codec->spec);
434} 460}
435 461
436static struct snd_kcontrol_new cxt_capture_mixers[] = { 462static const struct snd_kcontrol_new cxt_capture_mixers[] = {
437 { 463 {
438 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 464 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
439 .name = "Capture Source", 465 .name = "Capture Source",
@@ -446,7 +472,7 @@ static struct snd_kcontrol_new cxt_capture_mixers[] = {
446 472
447#ifdef CONFIG_SND_HDA_INPUT_BEEP 473#ifdef CONFIG_SND_HDA_INPUT_BEEP
448/* additional beep mixers; the actual parameters are overwritten at build */ 474/* additional beep mixers; the actual parameters are overwritten at build */
449static struct snd_kcontrol_new cxt_beep_mixer[] = { 475static const struct snd_kcontrol_new cxt_beep_mixer[] = {
450 HDA_CODEC_VOLUME_MONO("Beep Playback Volume", 0, 1, 0, HDA_OUTPUT), 476 HDA_CODEC_VOLUME_MONO("Beep Playback Volume", 0, 1, 0, HDA_OUTPUT),
451 HDA_CODEC_MUTE_BEEP_MONO("Beep Playback Switch", 0, 1, 0, HDA_OUTPUT), 477 HDA_CODEC_MUTE_BEEP_MONO("Beep Playback Switch", 0, 1, 0, HDA_OUTPUT),
452 { } /* end */ 478 { } /* end */
@@ -456,12 +482,18 @@ static struct snd_kcontrol_new cxt_beep_mixer[] = {
456static const char * const slave_vols[] = { 482static const char * const slave_vols[] = {
457 "Headphone Playback Volume", 483 "Headphone Playback Volume",
458 "Speaker Playback Volume", 484 "Speaker Playback Volume",
485 "Front Playback Volume",
486 "Surround Playback Volume",
487 "CLFE Playback Volume",
459 NULL 488 NULL
460}; 489};
461 490
462static const char * const slave_sws[] = { 491static const char * const slave_sws[] = {
463 "Headphone Playback Switch", 492 "Headphone Playback Switch",
464 "Speaker Playback Switch", 493 "Speaker Playback Switch",
494 "Front Playback Switch",
495 "Surround Playback Switch",
496 "CLFE Playback Switch",
465 NULL 497 NULL
466}; 498};
467 499
@@ -521,7 +553,7 @@ static int conexant_build_controls(struct hda_codec *codec)
521#ifdef CONFIG_SND_HDA_INPUT_BEEP 553#ifdef CONFIG_SND_HDA_INPUT_BEEP
522 /* create beep controls if needed */ 554 /* create beep controls if needed */
523 if (spec->beep_amp) { 555 if (spec->beep_amp) {
524 struct snd_kcontrol_new *knew; 556 const struct snd_kcontrol_new *knew;
525 for (knew = cxt_beep_mixer; knew->name; knew++) { 557 for (knew = cxt_beep_mixer; knew->name; knew++) {
526 struct snd_kcontrol *kctl; 558 struct snd_kcontrol *kctl;
527 kctl = snd_ctl_new1(knew, codec); 559 kctl = snd_ctl_new1(knew, codec);
@@ -546,7 +578,7 @@ static int conexant_suspend(struct hda_codec *codec, pm_message_t state)
546} 578}
547#endif 579#endif
548 580
549static struct hda_codec_ops conexant_patch_ops = { 581static const struct hda_codec_ops conexant_patch_ops = {
550 .build_controls = conexant_build_controls, 582 .build_controls = conexant_build_controls,
551 .build_pcms = conexant_build_pcms, 583 .build_pcms = conexant_build_pcms,
552 .init = conexant_init, 584 .init = conexant_init,
@@ -564,6 +596,7 @@ static struct hda_codec_ops conexant_patch_ops = {
564#define set_beep_amp(spec, nid, idx, dir) /* NOP */ 596#define set_beep_amp(spec, nid, idx, dir) /* NOP */
565#endif 597#endif
566 598
599static int patch_conexant_auto(struct hda_codec *codec);
567/* 600/*
568 * EAPD control 601 * EAPD control
569 * the private value = nid | (invert << 8) 602 * the private value = nid | (invert << 8)
@@ -662,16 +695,16 @@ static int conexant_ch_mode_put(struct snd_kcontrol *kcontrol,
662 695
663/* Conexant 5045 specific */ 696/* Conexant 5045 specific */
664 697
665static hda_nid_t cxt5045_dac_nids[1] = { 0x19 }; 698static const hda_nid_t cxt5045_dac_nids[1] = { 0x19 };
666static hda_nid_t cxt5045_adc_nids[1] = { 0x1a }; 699static const hda_nid_t cxt5045_adc_nids[1] = { 0x1a };
667static hda_nid_t cxt5045_capsrc_nids[1] = { 0x1a }; 700static const hda_nid_t cxt5045_capsrc_nids[1] = { 0x1a };
668#define CXT5045_SPDIF_OUT 0x18 701#define CXT5045_SPDIF_OUT 0x18
669 702
670static struct hda_channel_mode cxt5045_modes[1] = { 703static const struct hda_channel_mode cxt5045_modes[1] = {
671 { 2, NULL }, 704 { 2, NULL },
672}; 705};
673 706
674static struct hda_input_mux cxt5045_capture_source = { 707static const struct hda_input_mux cxt5045_capture_source = {
675 .num_items = 2, 708 .num_items = 2,
676 .items = { 709 .items = {
677 { "IntMic", 0x1 }, 710 { "IntMic", 0x1 },
@@ -679,7 +712,7 @@ static struct hda_input_mux cxt5045_capture_source = {
679 } 712 }
680}; 713};
681 714
682static struct hda_input_mux cxt5045_capture_source_benq = { 715static const struct hda_input_mux cxt5045_capture_source_benq = {
683 .num_items = 5, 716 .num_items = 5,
684 .items = { 717 .items = {
685 { "IntMic", 0x1 }, 718 { "IntMic", 0x1 },
@@ -690,7 +723,7 @@ static struct hda_input_mux cxt5045_capture_source_benq = {
690 } 723 }
691}; 724};
692 725
693static struct hda_input_mux cxt5045_capture_source_hp530 = { 726static const struct hda_input_mux cxt5045_capture_source_hp530 = {
694 .num_items = 2, 727 .num_items = 2,
695 .items = { 728 .items = {
696 { "ExtMic", 0x1 }, 729 { "ExtMic", 0x1 },
@@ -723,7 +756,7 @@ static int cxt5045_hp_master_sw_put(struct snd_kcontrol *kcontrol,
723} 756}
724 757
725/* bind volumes of both NID 0x10 and 0x11 */ 758/* bind volumes of both NID 0x10 and 0x11 */
726static struct hda_bind_ctls cxt5045_hp_bind_master_vol = { 759static const struct hda_bind_ctls cxt5045_hp_bind_master_vol = {
727 .ops = &snd_hda_bind_vol, 760 .ops = &snd_hda_bind_vol,
728 .values = { 761 .values = {
729 HDA_COMPOSE_AMP_VAL(0x10, 3, 0, HDA_OUTPUT), 762 HDA_COMPOSE_AMP_VAL(0x10, 3, 0, HDA_OUTPUT),
@@ -735,12 +768,12 @@ static struct hda_bind_ctls cxt5045_hp_bind_master_vol = {
735/* toggle input of built-in and mic jack appropriately */ 768/* toggle input of built-in and mic jack appropriately */
736static void cxt5045_hp_automic(struct hda_codec *codec) 769static void cxt5045_hp_automic(struct hda_codec *codec)
737{ 770{
738 static struct hda_verb mic_jack_on[] = { 771 static const struct hda_verb mic_jack_on[] = {
739 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 772 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
740 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 773 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
741 {} 774 {}
742 }; 775 };
743 static struct hda_verb mic_jack_off[] = { 776 static const struct hda_verb mic_jack_off[] = {
744 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 777 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
745 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 778 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
746 {} 779 {}
@@ -784,7 +817,7 @@ static void cxt5045_hp_unsol_event(struct hda_codec *codec,
784 } 817 }
785} 818}
786 819
787static struct snd_kcontrol_new cxt5045_mixers[] = { 820static const struct snd_kcontrol_new cxt5045_mixers[] = {
788 HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x01, HDA_INPUT), 821 HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x01, HDA_INPUT),
789 HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x01, HDA_INPUT), 822 HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x01, HDA_INPUT),
790 HDA_CODEC_VOLUME("Mic Capture Volume", 0x1a, 0x02, HDA_INPUT), 823 HDA_CODEC_VOLUME("Mic Capture Volume", 0x1a, 0x02, HDA_INPUT),
@@ -808,7 +841,7 @@ static struct snd_kcontrol_new cxt5045_mixers[] = {
808 {} 841 {}
809}; 842};
810 843
811static struct snd_kcontrol_new cxt5045_benq_mixers[] = { 844static const struct snd_kcontrol_new cxt5045_benq_mixers[] = {
812 HDA_CODEC_VOLUME("CD Capture Volume", 0x1a, 0x04, HDA_INPUT), 845 HDA_CODEC_VOLUME("CD Capture Volume", 0x1a, 0x04, HDA_INPUT),
813 HDA_CODEC_MUTE("CD Capture Switch", 0x1a, 0x04, HDA_INPUT), 846 HDA_CODEC_MUTE("CD Capture Switch", 0x1a, 0x04, HDA_INPUT),
814 HDA_CODEC_VOLUME("CD Playback Volume", 0x17, 0x4, HDA_INPUT), 847 HDA_CODEC_VOLUME("CD Playback Volume", 0x17, 0x4, HDA_INPUT),
@@ -825,7 +858,7 @@ static struct snd_kcontrol_new cxt5045_benq_mixers[] = {
825 {} 858 {}
826}; 859};
827 860
828static struct snd_kcontrol_new cxt5045_mixers_hp530[] = { 861static const struct snd_kcontrol_new cxt5045_mixers_hp530[] = {
829 HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x02, HDA_INPUT), 862 HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x02, HDA_INPUT),
830 HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x02, HDA_INPUT), 863 HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x02, HDA_INPUT),
831 HDA_CODEC_VOLUME("Mic Capture Volume", 0x1a, 0x01, HDA_INPUT), 864 HDA_CODEC_VOLUME("Mic Capture Volume", 0x1a, 0x01, HDA_INPUT),
@@ -849,7 +882,7 @@ static struct snd_kcontrol_new cxt5045_mixers_hp530[] = {
849 {} 882 {}
850}; 883};
851 884
852static struct hda_verb cxt5045_init_verbs[] = { 885static const struct hda_verb cxt5045_init_verbs[] = {
853 /* Line in, Mic */ 886 /* Line in, Mic */
854 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, 887 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
855 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, 888 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
@@ -875,7 +908,7 @@ static struct hda_verb cxt5045_init_verbs[] = {
875 { } /* end */ 908 { } /* end */
876}; 909};
877 910
878static struct hda_verb cxt5045_benq_init_verbs[] = { 911static const struct hda_verb cxt5045_benq_init_verbs[] = {
879 /* Internal Mic, Mic */ 912 /* Internal Mic, Mic */
880 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, 913 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
881 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, 914 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
@@ -901,13 +934,13 @@ static struct hda_verb cxt5045_benq_init_verbs[] = {
901 { } /* end */ 934 { } /* end */
902}; 935};
903 936
904static struct hda_verb cxt5045_hp_sense_init_verbs[] = { 937static const struct hda_verb cxt5045_hp_sense_init_verbs[] = {
905 /* pin sensing on HP jack */ 938 /* pin sensing on HP jack */
906 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, 939 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
907 { } /* end */ 940 { } /* end */
908}; 941};
909 942
910static struct hda_verb cxt5045_mic_sense_init_verbs[] = { 943static const struct hda_verb cxt5045_mic_sense_init_verbs[] = {
911 /* pin sensing on HP jack */ 944 /* pin sensing on HP jack */
912 {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT}, 945 {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
913 { } /* end */ 946 { } /* end */
@@ -917,7 +950,7 @@ static struct hda_verb cxt5045_mic_sense_init_verbs[] = {
917/* Test configuration for debugging, modelled after the ALC260 test 950/* Test configuration for debugging, modelled after the ALC260 test
918 * configuration. 951 * configuration.
919 */ 952 */
920static struct hda_input_mux cxt5045_test_capture_source = { 953static const struct hda_input_mux cxt5045_test_capture_source = {
921 .num_items = 5, 954 .num_items = 5,
922 .items = { 955 .items = {
923 { "MIXER", 0x0 }, 956 { "MIXER", 0x0 },
@@ -928,7 +961,7 @@ static struct hda_input_mux cxt5045_test_capture_source = {
928 }, 961 },
929}; 962};
930 963
931static struct snd_kcontrol_new cxt5045_test_mixer[] = { 964static const struct snd_kcontrol_new cxt5045_test_mixer[] = {
932 965
933 /* Output controls */ 966 /* Output controls */
934 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x10, 0x0, HDA_OUTPUT), 967 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x10, 0x0, HDA_OUTPUT),
@@ -978,7 +1011,7 @@ static struct snd_kcontrol_new cxt5045_test_mixer[] = {
978 { } /* end */ 1011 { } /* end */
979}; 1012};
980 1013
981static struct hda_verb cxt5045_test_init_verbs[] = { 1014static const struct hda_verb cxt5045_test_init_verbs[] = {
982 /* Set connections */ 1015 /* Set connections */
983 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 }, 1016 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
984 { 0x11, AC_VERB_SET_CONNECT_SEL, 0x0 }, 1017 { 0x11, AC_VERB_SET_CONNECT_SEL, 0x0 },
@@ -1047,6 +1080,7 @@ enum {
1047#ifdef CONFIG_SND_DEBUG 1080#ifdef CONFIG_SND_DEBUG
1048 CXT5045_TEST, 1081 CXT5045_TEST,
1049#endif 1082#endif
1083 CXT5045_AUTO,
1050 CXT5045_MODELS 1084 CXT5045_MODELS
1051}; 1085};
1052 1086
@@ -1059,9 +1093,10 @@ static const char * const cxt5045_models[CXT5045_MODELS] = {
1059#ifdef CONFIG_SND_DEBUG 1093#ifdef CONFIG_SND_DEBUG
1060 [CXT5045_TEST] = "test", 1094 [CXT5045_TEST] = "test",
1061#endif 1095#endif
1096 [CXT5045_AUTO] = "auto",
1062}; 1097};
1063 1098
1064static struct snd_pci_quirk cxt5045_cfg_tbl[] = { 1099static const struct snd_pci_quirk cxt5045_cfg_tbl[] = {
1065 SND_PCI_QUIRK(0x103c, 0x30d5, "HP 530", CXT5045_LAPTOP_HP530), 1100 SND_PCI_QUIRK(0x103c, 0x30d5, "HP 530", CXT5045_LAPTOP_HP530),
1066 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP DV Series", 1101 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP DV Series",
1067 CXT5045_LAPTOP_HPSENSE), 1102 CXT5045_LAPTOP_HPSENSE),
@@ -1085,6 +1120,16 @@ static int patch_cxt5045(struct hda_codec *codec)
1085 struct conexant_spec *spec; 1120 struct conexant_spec *spec;
1086 int board_config; 1121 int board_config;
1087 1122
1123 board_config = snd_hda_check_board_config(codec, CXT5045_MODELS,
1124 cxt5045_models,
1125 cxt5045_cfg_tbl);
1126#if 0 /* use the old method just for safety */
1127 if (board_config < 0)
1128 board_config = CXT5045_AUTO;
1129#endif
1130 if (board_config == CXT5045_AUTO)
1131 return patch_conexant_auto(codec);
1132
1088 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 1133 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1089 if (!spec) 1134 if (!spec)
1090 return -ENOMEM; 1135 return -ENOMEM;
@@ -1111,9 +1156,6 @@ static int patch_cxt5045(struct hda_codec *codec)
1111 1156
1112 codec->patch_ops = conexant_patch_ops; 1157 codec->patch_ops = conexant_patch_ops;
1113 1158
1114 board_config = snd_hda_check_board_config(codec, CXT5045_MODELS,
1115 cxt5045_models,
1116 cxt5045_cfg_tbl);
1117 switch (board_config) { 1159 switch (board_config) {
1118 case CXT5045_LAPTOP_HPSENSE: 1160 case CXT5045_LAPTOP_HPSENSE:
1119 codec->patch_ops.unsol_event = cxt5045_hp_unsol_event; 1161 codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
@@ -1196,15 +1238,15 @@ static int patch_cxt5045(struct hda_codec *codec)
1196/* Conexant 5047 specific */ 1238/* Conexant 5047 specific */
1197#define CXT5047_SPDIF_OUT 0x11 1239#define CXT5047_SPDIF_OUT 0x11
1198 1240
1199static hda_nid_t cxt5047_dac_nids[1] = { 0x10 }; /* 0x1c */ 1241static const hda_nid_t cxt5047_dac_nids[1] = { 0x10 }; /* 0x1c */
1200static hda_nid_t cxt5047_adc_nids[1] = { 0x12 }; 1242static const hda_nid_t cxt5047_adc_nids[1] = { 0x12 };
1201static hda_nid_t cxt5047_capsrc_nids[1] = { 0x1a }; 1243static const hda_nid_t cxt5047_capsrc_nids[1] = { 0x1a };
1202 1244
1203static struct hda_channel_mode cxt5047_modes[1] = { 1245static const struct hda_channel_mode cxt5047_modes[1] = {
1204 { 2, NULL }, 1246 { 2, NULL },
1205}; 1247};
1206 1248
1207static struct hda_input_mux cxt5047_toshiba_capture_source = { 1249static const struct hda_input_mux cxt5047_toshiba_capture_source = {
1208 .num_items = 2, 1250 .num_items = 2,
1209 .items = { 1251 .items = {
1210 { "ExtMic", 0x2 }, 1252 { "ExtMic", 0x2 },
@@ -1256,12 +1298,12 @@ static void cxt5047_hp_automute(struct hda_codec *codec)
1256/* toggle input of built-in and mic jack appropriately */ 1298/* toggle input of built-in and mic jack appropriately */
1257static void cxt5047_hp_automic(struct hda_codec *codec) 1299static void cxt5047_hp_automic(struct hda_codec *codec)
1258{ 1300{
1259 static struct hda_verb mic_jack_on[] = { 1301 static const struct hda_verb mic_jack_on[] = {
1260 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1302 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1261 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1303 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1262 {} 1304 {}
1263 }; 1305 };
1264 static struct hda_verb mic_jack_off[] = { 1306 static const struct hda_verb mic_jack_off[] = {
1265 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1307 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1266 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1308 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1267 {} 1309 {}
@@ -1289,7 +1331,7 @@ static void cxt5047_hp_unsol_event(struct hda_codec *codec,
1289 } 1331 }
1290} 1332}
1291 1333
1292static struct snd_kcontrol_new cxt5047_base_mixers[] = { 1334static const struct snd_kcontrol_new cxt5047_base_mixers[] = {
1293 HDA_CODEC_VOLUME("Mic Playback Volume", 0x19, 0x02, HDA_INPUT), 1335 HDA_CODEC_VOLUME("Mic Playback Volume", 0x19, 0x02, HDA_INPUT),
1294 HDA_CODEC_MUTE("Mic Playback Switch", 0x19, 0x02, HDA_INPUT), 1336 HDA_CODEC_MUTE("Mic Playback Switch", 0x19, 0x02, HDA_INPUT),
1295 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1a, 0x0, HDA_OUTPUT), 1337 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1a, 0x0, HDA_OUTPUT),
@@ -1309,19 +1351,19 @@ static struct snd_kcontrol_new cxt5047_base_mixers[] = {
1309 {} 1351 {}
1310}; 1352};
1311 1353
1312static struct snd_kcontrol_new cxt5047_hp_spk_mixers[] = { 1354static const struct snd_kcontrol_new cxt5047_hp_spk_mixers[] = {
1313 /* See the note in cxt5047_hp_master_sw_put */ 1355 /* See the note in cxt5047_hp_master_sw_put */
1314 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x01, HDA_OUTPUT), 1356 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x01, HDA_OUTPUT),
1315 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x13, 0x00, HDA_OUTPUT), 1357 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x13, 0x00, HDA_OUTPUT),
1316 {} 1358 {}
1317}; 1359};
1318 1360
1319static struct snd_kcontrol_new cxt5047_hp_only_mixers[] = { 1361static const struct snd_kcontrol_new cxt5047_hp_only_mixers[] = {
1320 HDA_CODEC_VOLUME("Master Playback Volume", 0x13, 0x00, HDA_OUTPUT), 1362 HDA_CODEC_VOLUME("Master Playback Volume", 0x13, 0x00, HDA_OUTPUT),
1321 { } /* end */ 1363 { } /* end */
1322}; 1364};
1323 1365
1324static struct hda_verb cxt5047_init_verbs[] = { 1366static const struct hda_verb cxt5047_init_verbs[] = {
1325 /* Line in, Mic, Built-in Mic */ 1367 /* Line in, Mic, Built-in Mic */
1326 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 1368 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1327 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 }, 1369 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 },
@@ -1348,7 +1390,7 @@ static struct hda_verb cxt5047_init_verbs[] = {
1348}; 1390};
1349 1391
1350/* configuration for Toshiba Laptops */ 1392/* configuration for Toshiba Laptops */
1351static struct hda_verb cxt5047_toshiba_init_verbs[] = { 1393static const struct hda_verb cxt5047_toshiba_init_verbs[] = {
1352 {0x13, AC_VERB_SET_EAPD_BTLENABLE, 0x0}, /* default off */ 1394 {0x13, AC_VERB_SET_EAPD_BTLENABLE, 0x0}, /* default off */
1353 {} 1395 {}
1354}; 1396};
@@ -1357,7 +1399,7 @@ static struct hda_verb cxt5047_toshiba_init_verbs[] = {
1357 * configuration. 1399 * configuration.
1358 */ 1400 */
1359#ifdef CONFIG_SND_DEBUG 1401#ifdef CONFIG_SND_DEBUG
1360static struct hda_input_mux cxt5047_test_capture_source = { 1402static const struct hda_input_mux cxt5047_test_capture_source = {
1361 .num_items = 4, 1403 .num_items = 4,
1362 .items = { 1404 .items = {
1363 { "LINE1 pin", 0x0 }, 1405 { "LINE1 pin", 0x0 },
@@ -1367,7 +1409,7 @@ static struct hda_input_mux cxt5047_test_capture_source = {
1367 }, 1409 },
1368}; 1410};
1369 1411
1370static struct snd_kcontrol_new cxt5047_test_mixer[] = { 1412static const struct snd_kcontrol_new cxt5047_test_mixer[] = {
1371 1413
1372 /* Output only controls */ 1414 /* Output only controls */
1373 HDA_CODEC_VOLUME("OutAmp-1 Volume", 0x10, 0x0, HDA_OUTPUT), 1415 HDA_CODEC_VOLUME("OutAmp-1 Volume", 0x10, 0x0, HDA_OUTPUT),
@@ -1420,7 +1462,7 @@ static struct snd_kcontrol_new cxt5047_test_mixer[] = {
1420 { } /* end */ 1462 { } /* end */
1421}; 1463};
1422 1464
1423static struct hda_verb cxt5047_test_init_verbs[] = { 1465static const struct hda_verb cxt5047_test_init_verbs[] = {
1424 /* Enable retasking pins as output, initially without power amp */ 1466 /* Enable retasking pins as output, initially without power amp */
1425 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1467 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1426 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1468 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
@@ -1492,6 +1534,7 @@ enum {
1492#ifdef CONFIG_SND_DEBUG 1534#ifdef CONFIG_SND_DEBUG
1493 CXT5047_TEST, 1535 CXT5047_TEST,
1494#endif 1536#endif
1537 CXT5047_AUTO,
1495 CXT5047_MODELS 1538 CXT5047_MODELS
1496}; 1539};
1497 1540
@@ -1502,9 +1545,10 @@ static const char * const cxt5047_models[CXT5047_MODELS] = {
1502#ifdef CONFIG_SND_DEBUG 1545#ifdef CONFIG_SND_DEBUG
1503 [CXT5047_TEST] = "test", 1546 [CXT5047_TEST] = "test",
1504#endif 1547#endif
1548 [CXT5047_AUTO] = "auto",
1505}; 1549};
1506 1550
1507static struct snd_pci_quirk cxt5047_cfg_tbl[] = { 1551static const struct snd_pci_quirk cxt5047_cfg_tbl[] = {
1508 SND_PCI_QUIRK(0x103c, 0x30a5, "HP DV5200T/DV8000T", CXT5047_LAPTOP_HP), 1552 SND_PCI_QUIRK(0x103c, 0x30a5, "HP DV5200T/DV8000T", CXT5047_LAPTOP_HP),
1509 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP DV Series", 1553 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP DV Series",
1510 CXT5047_LAPTOP), 1554 CXT5047_LAPTOP),
@@ -1517,6 +1561,16 @@ static int patch_cxt5047(struct hda_codec *codec)
1517 struct conexant_spec *spec; 1561 struct conexant_spec *spec;
1518 int board_config; 1562 int board_config;
1519 1563
1564 board_config = snd_hda_check_board_config(codec, CXT5047_MODELS,
1565 cxt5047_models,
1566 cxt5047_cfg_tbl);
1567#if 0 /* not enabled as default, as BIOS often broken for this codec */
1568 if (board_config < 0)
1569 board_config = CXT5047_AUTO;
1570#endif
1571 if (board_config == CXT5047_AUTO)
1572 return patch_conexant_auto(codec);
1573
1520 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 1574 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1521 if (!spec) 1575 if (!spec)
1522 return -ENOMEM; 1576 return -ENOMEM;
@@ -1540,9 +1594,6 @@ static int patch_cxt5047(struct hda_codec *codec)
1540 1594
1541 codec->patch_ops = conexant_patch_ops; 1595 codec->patch_ops = conexant_patch_ops;
1542 1596
1543 board_config = snd_hda_check_board_config(codec, CXT5047_MODELS,
1544 cxt5047_models,
1545 cxt5047_cfg_tbl);
1546 switch (board_config) { 1597 switch (board_config) {
1547 case CXT5047_LAPTOP: 1598 case CXT5047_LAPTOP:
1548 spec->num_mixers = 2; 1599 spec->num_mixers = 2;
@@ -1591,10 +1642,10 @@ static int patch_cxt5047(struct hda_codec *codec)
1591} 1642}
1592 1643
1593/* Conexant 5051 specific */ 1644/* Conexant 5051 specific */
1594static hda_nid_t cxt5051_dac_nids[1] = { 0x10 }; 1645static const hda_nid_t cxt5051_dac_nids[1] = { 0x10 };
1595static hda_nid_t cxt5051_adc_nids[2] = { 0x14, 0x15 }; 1646static const hda_nid_t cxt5051_adc_nids[2] = { 0x14, 0x15 };
1596 1647
1597static struct hda_channel_mode cxt5051_modes[1] = { 1648static const struct hda_channel_mode cxt5051_modes[1] = {
1598 { 2, NULL }, 1649 { 2, NULL },
1599}; 1650};
1600 1651
@@ -1696,7 +1747,7 @@ static void cxt5051_hp_unsol_event(struct hda_codec *codec,
1696 snd_hda_input_jack_report(codec, nid); 1747 snd_hda_input_jack_report(codec, nid);
1697} 1748}
1698 1749
1699static struct snd_kcontrol_new cxt5051_playback_mixers[] = { 1750static const struct snd_kcontrol_new cxt5051_playback_mixers[] = {
1700 HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT), 1751 HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
1701 { 1752 {
1702 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1753 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -1709,7 +1760,7 @@ static struct snd_kcontrol_new cxt5051_playback_mixers[] = {
1709 {} 1760 {}
1710}; 1761};
1711 1762
1712static struct snd_kcontrol_new cxt5051_capture_mixers[] = { 1763static const struct snd_kcontrol_new cxt5051_capture_mixers[] = {
1713 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT), 1764 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1714 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT), 1765 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1715 HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT), 1766 HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT),
@@ -1719,7 +1770,7 @@ static struct snd_kcontrol_new cxt5051_capture_mixers[] = {
1719 {} 1770 {}
1720}; 1771};
1721 1772
1722static struct snd_kcontrol_new cxt5051_hp_mixers[] = { 1773static const struct snd_kcontrol_new cxt5051_hp_mixers[] = {
1723 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT), 1774 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1724 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT), 1775 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1725 HDA_CODEC_VOLUME("Mic Volume", 0x15, 0x00, HDA_INPUT), 1776 HDA_CODEC_VOLUME("Mic Volume", 0x15, 0x00, HDA_INPUT),
@@ -1727,19 +1778,19 @@ static struct snd_kcontrol_new cxt5051_hp_mixers[] = {
1727 {} 1778 {}
1728}; 1779};
1729 1780
1730static struct snd_kcontrol_new cxt5051_hp_dv6736_mixers[] = { 1781static const struct snd_kcontrol_new cxt5051_hp_dv6736_mixers[] = {
1731 HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x00, HDA_INPUT), 1782 HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x00, HDA_INPUT),
1732 HDA_CODEC_MUTE("Capture Switch", 0x14, 0x00, HDA_INPUT), 1783 HDA_CODEC_MUTE("Capture Switch", 0x14, 0x00, HDA_INPUT),
1733 {} 1784 {}
1734}; 1785};
1735 1786
1736static struct snd_kcontrol_new cxt5051_f700_mixers[] = { 1787static const struct snd_kcontrol_new cxt5051_f700_mixers[] = {
1737 HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x01, HDA_INPUT), 1788 HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x01, HDA_INPUT),
1738 HDA_CODEC_MUTE("Capture Switch", 0x14, 0x01, HDA_INPUT), 1789 HDA_CODEC_MUTE("Capture Switch", 0x14, 0x01, HDA_INPUT),
1739 {} 1790 {}
1740}; 1791};
1741 1792
1742static struct snd_kcontrol_new cxt5051_toshiba_mixers[] = { 1793static const struct snd_kcontrol_new cxt5051_toshiba_mixers[] = {
1743 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT), 1794 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1744 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT), 1795 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1745 HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT), 1796 HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT),
@@ -1747,7 +1798,7 @@ static struct snd_kcontrol_new cxt5051_toshiba_mixers[] = {
1747 {} 1798 {}
1748}; 1799};
1749 1800
1750static struct hda_verb cxt5051_init_verbs[] = { 1801static const struct hda_verb cxt5051_init_verbs[] = {
1751 /* Line in, Mic */ 1802 /* Line in, Mic */
1752 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, 1803 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1753 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1804 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
@@ -1776,7 +1827,7 @@ static struct hda_verb cxt5051_init_verbs[] = {
1776 { } /* end */ 1827 { } /* end */
1777}; 1828};
1778 1829
1779static struct hda_verb cxt5051_hp_dv6736_init_verbs[] = { 1830static const struct hda_verb cxt5051_hp_dv6736_init_verbs[] = {
1780 /* Line in, Mic */ 1831 /* Line in, Mic */
1781 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, 1832 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1782 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1833 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
@@ -1801,7 +1852,7 @@ static struct hda_verb cxt5051_hp_dv6736_init_verbs[] = {
1801 { } /* end */ 1852 { } /* end */
1802}; 1853};
1803 1854
1804static struct hda_verb cxt5051_lenovo_x200_init_verbs[] = { 1855static const struct hda_verb cxt5051_lenovo_x200_init_verbs[] = {
1805 /* Line in, Mic */ 1856 /* Line in, Mic */
1806 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, 1857 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1807 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1858 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
@@ -1834,7 +1885,7 @@ static struct hda_verb cxt5051_lenovo_x200_init_verbs[] = {
1834 { } /* end */ 1885 { } /* end */
1835}; 1886};
1836 1887
1837static struct hda_verb cxt5051_f700_init_verbs[] = { 1888static const struct hda_verb cxt5051_f700_init_verbs[] = {
1838 /* Line in, Mic */ 1889 /* Line in, Mic */
1839 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, 1890 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1840 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1891 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
@@ -1869,7 +1920,7 @@ static void cxt5051_init_mic_port(struct hda_codec *codec, hda_nid_t nid,
1869 snd_hda_input_jack_report(codec, nid); 1920 snd_hda_input_jack_report(codec, nid);
1870} 1921}
1871 1922
1872static struct hda_verb cxt5051_ideapad_init_verbs[] = { 1923static const struct hda_verb cxt5051_ideapad_init_verbs[] = {
1873 /* Subwoofer */ 1924 /* Subwoofer */
1874 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1925 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1875 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 1926 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
@@ -1906,6 +1957,7 @@ enum {
1906 CXT5051_F700, /* HP Compaq Presario F700 */ 1957 CXT5051_F700, /* HP Compaq Presario F700 */
1907 CXT5051_TOSHIBA, /* Toshiba M300 & co */ 1958 CXT5051_TOSHIBA, /* Toshiba M300 & co */
1908 CXT5051_IDEAPAD, /* Lenovo IdeaPad Y430 */ 1959 CXT5051_IDEAPAD, /* Lenovo IdeaPad Y430 */
1960 CXT5051_AUTO, /* auto-parser */
1909 CXT5051_MODELS 1961 CXT5051_MODELS
1910}; 1962};
1911 1963
@@ -1917,9 +1969,10 @@ static const char *const cxt5051_models[CXT5051_MODELS] = {
1917 [CXT5051_F700] = "hp-700", 1969 [CXT5051_F700] = "hp-700",
1918 [CXT5051_TOSHIBA] = "toshiba", 1970 [CXT5051_TOSHIBA] = "toshiba",
1919 [CXT5051_IDEAPAD] = "ideapad", 1971 [CXT5051_IDEAPAD] = "ideapad",
1972 [CXT5051_AUTO] = "auto",
1920}; 1973};
1921 1974
1922static struct snd_pci_quirk cxt5051_cfg_tbl[] = { 1975static const struct snd_pci_quirk cxt5051_cfg_tbl[] = {
1923 SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV6736", CXT5051_HP_DV6736), 1976 SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV6736", CXT5051_HP_DV6736),
1924 SND_PCI_QUIRK(0x103c, 0x360b, "Compaq Presario CQ60", CXT5051_HP), 1977 SND_PCI_QUIRK(0x103c, 0x360b, "Compaq Presario CQ60", CXT5051_HP),
1925 SND_PCI_QUIRK(0x103c, 0x30ea, "Compaq Presario F700", CXT5051_F700), 1978 SND_PCI_QUIRK(0x103c, 0x30ea, "Compaq Presario F700", CXT5051_F700),
@@ -1937,6 +1990,16 @@ static int patch_cxt5051(struct hda_codec *codec)
1937 struct conexant_spec *spec; 1990 struct conexant_spec *spec;
1938 int board_config; 1991 int board_config;
1939 1992
1993 board_config = snd_hda_check_board_config(codec, CXT5051_MODELS,
1994 cxt5051_models,
1995 cxt5051_cfg_tbl);
1996#if 0 /* use the old method just for safety */
1997 if (board_config < 0)
1998 board_config = CXT5051_AUTO;
1999#endif
2000 if (board_config == CXT5051_AUTO)
2001 return patch_conexant_auto(codec);
2002
1940 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 2003 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1941 if (!spec) 2004 if (!spec)
1942 return -ENOMEM; 2005 return -ENOMEM;
@@ -1967,9 +2030,6 @@ static int patch_cxt5051(struct hda_codec *codec)
1967 2030
1968 codec->patch_ops.unsol_event = cxt5051_hp_unsol_event; 2031 codec->patch_ops.unsol_event = cxt5051_hp_unsol_event;
1969 2032
1970 board_config = snd_hda_check_board_config(codec, CXT5051_MODELS,
1971 cxt5051_models,
1972 cxt5051_cfg_tbl);
1973 spec->auto_mic = AUTO_MIC_PORTB | AUTO_MIC_PORTC; 2033 spec->auto_mic = AUTO_MIC_PORTB | AUTO_MIC_PORTC;
1974 switch (board_config) { 2034 switch (board_config) {
1975 case CXT5051_HP: 2035 case CXT5051_HP:
@@ -2011,17 +2071,17 @@ static int patch_cxt5051(struct hda_codec *codec)
2011 2071
2012/* Conexant 5066 specific */ 2072/* Conexant 5066 specific */
2013 2073
2014static hda_nid_t cxt5066_dac_nids[1] = { 0x10 }; 2074static const hda_nid_t cxt5066_dac_nids[1] = { 0x10 };
2015static hda_nid_t cxt5066_adc_nids[3] = { 0x14, 0x15, 0x16 }; 2075static const hda_nid_t cxt5066_adc_nids[3] = { 0x14, 0x15, 0x16 };
2016static hda_nid_t cxt5066_capsrc_nids[1] = { 0x17 }; 2076static const hda_nid_t cxt5066_capsrc_nids[1] = { 0x17 };
2017static hda_nid_t cxt5066_digout_pin_nids[2] = { 0x20, 0x22 }; 2077static const hda_nid_t cxt5066_digout_pin_nids[2] = { 0x20, 0x22 };
2018 2078
2019/* OLPC's microphone port is DC coupled for use with external sensors, 2079/* OLPC's microphone port is DC coupled for use with external sensors,
2020 * therefore we use a 50% mic bias in order to center the input signal with 2080 * therefore we use a 50% mic bias in order to center the input signal with
2021 * the DC input range of the codec. */ 2081 * the DC input range of the codec. */
2022#define CXT5066_OLPC_EXT_MIC_BIAS PIN_VREF50 2082#define CXT5066_OLPC_EXT_MIC_BIAS PIN_VREF50
2023 2083
2024static struct hda_channel_mode cxt5066_modes[1] = { 2084static const struct hda_channel_mode cxt5066_modes[1] = {
2025 { 2, NULL }, 2085 { 2, NULL },
2026}; 2086};
2027 2087
@@ -2176,7 +2236,7 @@ static void cxt5066_vostro_automic(struct hda_codec *codec)
2176 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2236 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2177 {} 2237 {}
2178 }; 2238 };
2179 static struct hda_verb ext_mic_absent[] = { 2239 static const struct hda_verb ext_mic_absent[] = {
2180 /* enable internal mic, port C */ 2240 /* enable internal mic, port C */
2181 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2241 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2182 2242
@@ -2209,7 +2269,7 @@ static void cxt5066_ideapad_automic(struct hda_codec *codec)
2209 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2269 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2210 {} 2270 {}
2211 }; 2271 };
2212 static struct hda_verb ext_mic_absent[] = { 2272 static const struct hda_verb ext_mic_absent[] = {
2213 {0x14, AC_VERB_SET_CONNECT_SEL, 2}, 2273 {0x14, AC_VERB_SET_CONNECT_SEL, 2},
2214 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2274 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2215 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2275 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
@@ -2257,7 +2317,7 @@ static void cxt5066_thinkpad_automic(struct hda_codec *codec)
2257{ 2317{
2258 unsigned int ext_present, dock_present; 2318 unsigned int ext_present, dock_present;
2259 2319
2260 static struct hda_verb ext_mic_present[] = { 2320 static const struct hda_verb ext_mic_present[] = {
2261 {0x14, AC_VERB_SET_CONNECT_SEL, 0}, 2321 {0x14, AC_VERB_SET_CONNECT_SEL, 0},
2262 {0x17, AC_VERB_SET_CONNECT_SEL, 1}, 2322 {0x17, AC_VERB_SET_CONNECT_SEL, 1},
2263 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2323 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
@@ -2265,7 +2325,7 @@ static void cxt5066_thinkpad_automic(struct hda_codec *codec)
2265 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2325 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2266 {} 2326 {}
2267 }; 2327 };
2268 static struct hda_verb dock_mic_present[] = { 2328 static const struct hda_verb dock_mic_present[] = {
2269 {0x14, AC_VERB_SET_CONNECT_SEL, 0}, 2329 {0x14, AC_VERB_SET_CONNECT_SEL, 0},
2270 {0x17, AC_VERB_SET_CONNECT_SEL, 0}, 2330 {0x17, AC_VERB_SET_CONNECT_SEL, 0},
2271 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2331 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
@@ -2273,7 +2333,7 @@ static void cxt5066_thinkpad_automic(struct hda_codec *codec)
2273 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2333 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2274 {} 2334 {}
2275 }; 2335 };
2276 static struct hda_verb ext_mic_absent[] = { 2336 static const struct hda_verb ext_mic_absent[] = {
2277 {0x14, AC_VERB_SET_CONNECT_SEL, 2}, 2337 {0x14, AC_VERB_SET_CONNECT_SEL, 2},
2278 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2338 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2279 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2339 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
@@ -2537,7 +2597,7 @@ static void cxt5066_olpc_capture_cleanup(struct hda_codec *codec)
2537} 2597}
2538 2598
2539static void conexant_check_dig_outs(struct hda_codec *codec, 2599static void conexant_check_dig_outs(struct hda_codec *codec,
2540 hda_nid_t *dig_pins, 2600 const hda_nid_t *dig_pins,
2541 int num_pins) 2601 int num_pins)
2542{ 2602{
2543 struct conexant_spec *spec = codec->spec; 2603 struct conexant_spec *spec = codec->spec;
@@ -2557,7 +2617,7 @@ static void conexant_check_dig_outs(struct hda_codec *codec,
2557 } 2617 }
2558} 2618}
2559 2619
2560static struct hda_input_mux cxt5066_capture_source = { 2620static const struct hda_input_mux cxt5066_capture_source = {
2561 .num_items = 4, 2621 .num_items = 4,
2562 .items = { 2622 .items = {
2563 { "Mic B", 0 }, 2623 { "Mic B", 0 },
@@ -2567,7 +2627,7 @@ static struct hda_input_mux cxt5066_capture_source = {
2567 }, 2627 },
2568}; 2628};
2569 2629
2570static struct hda_bind_ctls cxt5066_bind_capture_vol_others = { 2630static const struct hda_bind_ctls cxt5066_bind_capture_vol_others = {
2571 .ops = &snd_hda_bind_vol, 2631 .ops = &snd_hda_bind_vol,
2572 .values = { 2632 .values = {
2573 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_INPUT), 2633 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_INPUT),
@@ -2576,7 +2636,7 @@ static struct hda_bind_ctls cxt5066_bind_capture_vol_others = {
2576 }, 2636 },
2577}; 2637};
2578 2638
2579static struct hda_bind_ctls cxt5066_bind_capture_sw_others = { 2639static const struct hda_bind_ctls cxt5066_bind_capture_sw_others = {
2580 .ops = &snd_hda_bind_sw, 2640 .ops = &snd_hda_bind_sw,
2581 .values = { 2641 .values = {
2582 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_INPUT), 2642 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_INPUT),
@@ -2585,12 +2645,12 @@ static struct hda_bind_ctls cxt5066_bind_capture_sw_others = {
2585 }, 2645 },
2586}; 2646};
2587 2647
2588static struct snd_kcontrol_new cxt5066_mixer_master[] = { 2648static const struct snd_kcontrol_new cxt5066_mixer_master[] = {
2589 HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT), 2649 HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
2590 {} 2650 {}
2591}; 2651};
2592 2652
2593static struct snd_kcontrol_new cxt5066_mixer_master_olpc[] = { 2653static const struct snd_kcontrol_new cxt5066_mixer_master_olpc[] = {
2594 { 2654 {
2595 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2655 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2596 .name = "Master Playback Volume", 2656 .name = "Master Playback Volume",
@@ -2609,7 +2669,7 @@ static struct snd_kcontrol_new cxt5066_mixer_master_olpc[] = {
2609 {} 2669 {}
2610}; 2670};
2611 2671
2612static struct snd_kcontrol_new cxt5066_mixer_olpc_dc[] = { 2672static const struct snd_kcontrol_new cxt5066_mixer_olpc_dc[] = {
2613 { 2673 {
2614 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2674 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2615 .name = "DC Mode Enable Switch", 2675 .name = "DC Mode Enable Switch",
@@ -2627,7 +2687,7 @@ static struct snd_kcontrol_new cxt5066_mixer_olpc_dc[] = {
2627 {} 2687 {}
2628}; 2688};
2629 2689
2630static struct snd_kcontrol_new cxt5066_mixers[] = { 2690static const struct snd_kcontrol_new cxt5066_mixers[] = {
2631 { 2691 {
2632 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2692 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2633 .name = "Master Playback Switch", 2693 .name = "Master Playback Switch",
@@ -2650,7 +2710,7 @@ static struct snd_kcontrol_new cxt5066_mixers[] = {
2650 {} 2710 {}
2651}; 2711};
2652 2712
2653static struct snd_kcontrol_new cxt5066_vostro_mixers[] = { 2713static const struct snd_kcontrol_new cxt5066_vostro_mixers[] = {
2654 { 2714 {
2655 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2715 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2656 .name = "Internal Mic Boost Capture Enum", 2716 .name = "Internal Mic Boost Capture Enum",
@@ -2662,7 +2722,7 @@ static struct snd_kcontrol_new cxt5066_vostro_mixers[] = {
2662 {} 2722 {}
2663}; 2723};
2664 2724
2665static struct hda_verb cxt5066_init_verbs[] = { 2725static const struct hda_verb cxt5066_init_verbs[] = {
2666 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */ 2726 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */
2667 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */ 2727 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */
2668 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */ 2728 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */
@@ -2717,7 +2777,7 @@ static struct hda_verb cxt5066_init_verbs[] = {
2717 { } /* end */ 2777 { } /* end */
2718}; 2778};
2719 2779
2720static struct hda_verb cxt5066_init_verbs_olpc[] = { 2780static const struct hda_verb cxt5066_init_verbs_olpc[] = {
2721 /* Port A: headphones */ 2781 /* Port A: headphones */
2722 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2782 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2723 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ 2783 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
@@ -2778,7 +2838,7 @@ static struct hda_verb cxt5066_init_verbs_olpc[] = {
2778 { } /* end */ 2838 { } /* end */
2779}; 2839};
2780 2840
2781static struct hda_verb cxt5066_init_verbs_vostro[] = { 2841static const struct hda_verb cxt5066_init_verbs_vostro[] = {
2782 /* Port A: headphones */ 2842 /* Port A: headphones */
2783 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2843 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2784 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ 2844 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
@@ -2839,7 +2899,7 @@ static struct hda_verb cxt5066_init_verbs_vostro[] = {
2839 { } /* end */ 2899 { } /* end */
2840}; 2900};
2841 2901
2842static struct hda_verb cxt5066_init_verbs_ideapad[] = { 2902static const struct hda_verb cxt5066_init_verbs_ideapad[] = {
2843 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */ 2903 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */
2844 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */ 2904 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */
2845 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */ 2905 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */
@@ -2889,7 +2949,7 @@ static struct hda_verb cxt5066_init_verbs_ideapad[] = {
2889 { } /* end */ 2949 { } /* end */
2890}; 2950};
2891 2951
2892static struct hda_verb cxt5066_init_verbs_thinkpad[] = { 2952static const struct hda_verb cxt5066_init_verbs_thinkpad[] = {
2893 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */ 2953 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */
2894 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port E */ 2954 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port E */
2895 2955
@@ -2947,13 +3007,13 @@ static struct hda_verb cxt5066_init_verbs_thinkpad[] = {
2947 { } /* end */ 3007 { } /* end */
2948}; 3008};
2949 3009
2950static struct hda_verb cxt5066_init_verbs_portd_lo[] = { 3010static const struct hda_verb cxt5066_init_verbs_portd_lo[] = {
2951 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3011 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2952 { } /* end */ 3012 { } /* end */
2953}; 3013};
2954 3014
2955 3015
2956static struct hda_verb cxt5066_init_verbs_hp_laptop[] = { 3016static const struct hda_verb cxt5066_init_verbs_hp_laptop[] = {
2957 {0x14, AC_VERB_SET_CONNECT_SEL, 0x0}, 3017 {0x14, AC_VERB_SET_CONNECT_SEL, 0x0},
2958 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, 3018 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
2959 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT}, 3019 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
@@ -2997,6 +3057,7 @@ enum {
2997 CXT5066_THINKPAD, /* Lenovo ThinkPad T410s, others? */ 3057 CXT5066_THINKPAD, /* Lenovo ThinkPad T410s, others? */
2998 CXT5066_ASUS, /* Asus K52JU, Lenovo G560 - Int mic at 0x1a and Ext mic at 0x1b */ 3058 CXT5066_ASUS, /* Asus K52JU, Lenovo G560 - Int mic at 0x1a and Ext mic at 0x1b */
2999 CXT5066_HP_LAPTOP, /* HP Laptop */ 3059 CXT5066_HP_LAPTOP, /* HP Laptop */
3060 CXT5066_AUTO, /* BIOS auto-parser */
3000 CXT5066_MODELS 3061 CXT5066_MODELS
3001}; 3062};
3002 3063
@@ -3009,9 +3070,10 @@ static const char * const cxt5066_models[CXT5066_MODELS] = {
3009 [CXT5066_THINKPAD] = "thinkpad", 3070 [CXT5066_THINKPAD] = "thinkpad",
3010 [CXT5066_ASUS] = "asus", 3071 [CXT5066_ASUS] = "asus",
3011 [CXT5066_HP_LAPTOP] = "hp-laptop", 3072 [CXT5066_HP_LAPTOP] = "hp-laptop",
3073 [CXT5066_AUTO] = "auto",
3012}; 3074};
3013 3075
3014static struct snd_pci_quirk cxt5066_cfg_tbl[] = { 3076static const struct snd_pci_quirk cxt5066_cfg_tbl[] = {
3015 SND_PCI_QUIRK_MASK(0x1025, 0xff00, 0x0400, "Acer", CXT5066_IDEAPAD), 3077 SND_PCI_QUIRK_MASK(0x1025, 0xff00, 0x0400, "Acer", CXT5066_IDEAPAD),
3016 SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTRO), 3078 SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTRO),
3017 SND_PCI_QUIRK(0x1028, 0x02f5, "Dell Vostro 320", CXT5066_IDEAPAD), 3079 SND_PCI_QUIRK(0x1028, 0x02f5, "Dell Vostro 320", CXT5066_IDEAPAD),
@@ -3046,6 +3108,15 @@ static int patch_cxt5066(struct hda_codec *codec)
3046 struct conexant_spec *spec; 3108 struct conexant_spec *spec;
3047 int board_config; 3109 int board_config;
3048 3110
3111 board_config = snd_hda_check_board_config(codec, CXT5066_MODELS,
3112 cxt5066_models, cxt5066_cfg_tbl);
3113#if 0 /* use the old method just for safety */
3114 if (board_config < 0)
3115 board_config = CXT5066_AUTO;
3116#endif
3117 if (board_config == CXT5066_AUTO)
3118 return patch_conexant_auto(codec);
3119
3049 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 3120 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3050 if (!spec) 3121 if (!spec)
3051 return -ENOMEM; 3122 return -ENOMEM;
@@ -3076,8 +3147,6 @@ static int patch_cxt5066(struct hda_codec *codec)
3076 3147
3077 set_beep_amp(spec, 0x13, 0, HDA_OUTPUT); 3148 set_beep_amp(spec, 0x13, 0, HDA_OUTPUT);
3078 3149
3079 board_config = snd_hda_check_board_config(codec, CXT5066_MODELS,
3080 cxt5066_models, cxt5066_cfg_tbl);
3081 switch (board_config) { 3150 switch (board_config) {
3082 default: 3151 default:
3083 case CXT5066_LAPTOP: 3152 case CXT5066_LAPTOP:
@@ -3195,7 +3264,45 @@ static int patch_cxt5066(struct hda_codec *codec)
3195 * Automatic parser for CX20641 & co 3264 * Automatic parser for CX20641 & co
3196 */ 3265 */
3197 3266
3198static hda_nid_t cx_auto_adc_nids[] = { 0x14 }; 3267static int cx_auto_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3268 struct hda_codec *codec,
3269 unsigned int stream_tag,
3270 unsigned int format,
3271 struct snd_pcm_substream *substream)
3272{
3273 struct conexant_spec *spec = codec->spec;
3274 hda_nid_t adc = spec->imux_info[spec->cur_mux[0]].adc;
3275 if (spec->adc_switching) {
3276 spec->cur_adc = adc;
3277 spec->cur_adc_stream_tag = stream_tag;
3278 spec->cur_adc_format = format;
3279 }
3280 snd_hda_codec_setup_stream(codec, adc, stream_tag, 0, format);
3281 return 0;
3282}
3283
3284static int cx_auto_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3285 struct hda_codec *codec,
3286 struct snd_pcm_substream *substream)
3287{
3288 struct conexant_spec *spec = codec->spec;
3289 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
3290 spec->cur_adc = 0;
3291 return 0;
3292}
3293
3294static const struct hda_pcm_stream cx_auto_pcm_analog_capture = {
3295 .substreams = 1,
3296 .channels_min = 2,
3297 .channels_max = 2,
3298 .nid = 0, /* fill later */
3299 .ops = {
3300 .prepare = cx_auto_capture_pcm_prepare,
3301 .cleanup = cx_auto_capture_pcm_cleanup
3302 },
3303};
3304
3305static const hda_nid_t cx_auto_adc_nids[] = { 0x14 };
3199 3306
3200/* get the connection index of @nid in the widget @mux */ 3307/* get the connection index of @nid in the widget @mux */
3201static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, 3308static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
@@ -3320,61 +3427,339 @@ static void cx_auto_parse_output(struct hda_codec *codec)
3320 spec->multiout.dac_nids = spec->private_dac_nids; 3427 spec->multiout.dac_nids = spec->private_dac_nids;
3321 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 3428 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3322 3429
3323 if (cfg->hp_outs > 0) 3430 for (i = 0; i < cfg->hp_outs; i++) {
3324 spec->auto_mute = 1; 3431 if (is_jack_detectable(codec, cfg->hp_pins[i])) {
3432 spec->auto_mute = 1;
3433 break;
3434 }
3435 }
3436 if (spec->auto_mute && cfg->line_out_pins[0] &&
3437 cfg->line_out_pins[0] != cfg->hp_pins[0] &&
3438 cfg->line_out_pins[0] != cfg->speaker_pins[0]) {
3439 for (i = 0; i < cfg->line_outs; i++) {
3440 if (is_jack_detectable(codec, cfg->line_out_pins[i])) {
3441 spec->detect_line = 1;
3442 break;
3443 }
3444 }
3445 spec->automute_lines = spec->detect_line;
3446 }
3447
3325 spec->vmaster_nid = spec->private_dac_nids[0]; 3448 spec->vmaster_nid = spec->private_dac_nids[0];
3326} 3449}
3327 3450
3451static void cx_auto_turn_eapd(struct hda_codec *codec, int num_pins,
3452 hda_nid_t *pins, bool on);
3453
3454static void do_automute(struct hda_codec *codec, int num_pins,
3455 hda_nid_t *pins, bool on)
3456{
3457 int i;
3458 for (i = 0; i < num_pins; i++)
3459 snd_hda_codec_write(codec, pins[i], 0,
3460 AC_VERB_SET_PIN_WIDGET_CONTROL,
3461 on ? PIN_OUT : 0);
3462 cx_auto_turn_eapd(codec, num_pins, pins, on);
3463}
3464
3465static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
3466{
3467 int i, present = 0;
3468
3469 for (i = 0; i < num_pins; i++) {
3470 hda_nid_t nid = pins[i];
3471 if (!nid || !is_jack_detectable(codec, nid))
3472 break;
3473 snd_hda_input_jack_report(codec, nid);
3474 present |= snd_hda_jack_detect(codec, nid);
3475 }
3476 return present;
3477}
3478
3328/* auto-mute/unmute speaker and line outs according to headphone jack */ 3479/* auto-mute/unmute speaker and line outs according to headphone jack */
3480static void cx_auto_update_speakers(struct hda_codec *codec)
3481{
3482 struct conexant_spec *spec = codec->spec;
3483 struct auto_pin_cfg *cfg = &spec->autocfg;
3484 int on;
3485
3486 if (!spec->auto_mute)
3487 on = 0;
3488 else
3489 on = spec->hp_present | spec->line_present;
3490 cx_auto_turn_eapd(codec, cfg->hp_outs, cfg->hp_pins, on);
3491 do_automute(codec, cfg->speaker_outs, cfg->speaker_pins, !on);
3492
3493 /* toggle line-out mutes if needed, too */
3494 /* if LO is a copy of either HP or Speaker, don't need to handle it */
3495 if (cfg->line_out_pins[0] == cfg->hp_pins[0] ||
3496 cfg->line_out_pins[0] == cfg->speaker_pins[0])
3497 return;
3498 if (!spec->automute_lines || !spec->auto_mute)
3499 on = 0;
3500 else
3501 on = spec->hp_present;
3502 do_automute(codec, cfg->line_outs, cfg->line_out_pins, !on);
3503}
3504
3329static void cx_auto_hp_automute(struct hda_codec *codec) 3505static void cx_auto_hp_automute(struct hda_codec *codec)
3330{ 3506{
3331 struct conexant_spec *spec = codec->spec; 3507 struct conexant_spec *spec = codec->spec;
3332 struct auto_pin_cfg *cfg = &spec->autocfg; 3508 struct auto_pin_cfg *cfg = &spec->autocfg;
3333 int i, present;
3334 3509
3335 if (!spec->auto_mute) 3510 if (!spec->auto_mute)
3336 return; 3511 return;
3337 present = 0; 3512 spec->hp_present = detect_jacks(codec, cfg->hp_outs, cfg->hp_pins);
3338 for (i = 0; i < cfg->hp_outs; i++) { 3513 cx_auto_update_speakers(codec);
3339 if (snd_hda_jack_detect(codec, cfg->hp_pins[i])) { 3514}
3340 present = 1; 3515
3341 break; 3516static void cx_auto_line_automute(struct hda_codec *codec)
3342 } 3517{
3518 struct conexant_spec *spec = codec->spec;
3519 struct auto_pin_cfg *cfg = &spec->autocfg;
3520
3521 if (!spec->auto_mute || !spec->detect_line)
3522 return;
3523 spec->line_present = detect_jacks(codec, cfg->line_outs,
3524 cfg->line_out_pins);
3525 cx_auto_update_speakers(codec);
3526}
3527
3528static int cx_automute_mode_info(struct snd_kcontrol *kcontrol,
3529 struct snd_ctl_elem_info *uinfo)
3530{
3531 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3532 struct conexant_spec *spec = codec->spec;
3533 static const char * const texts2[] = {
3534 "Disabled", "Enabled"
3535 };
3536 static const char * const texts3[] = {
3537 "Disabled", "Speaker Only", "Line-Out+Speaker"
3538 };
3539 const char * const *texts;
3540
3541 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3542 uinfo->count = 1;
3543 if (spec->automute_hp_lo) {
3544 uinfo->value.enumerated.items = 3;
3545 texts = texts3;
3546 } else {
3547 uinfo->value.enumerated.items = 2;
3548 texts = texts2;
3343 } 3549 }
3344 for (i = 0; i < cfg->line_outs; i++) { 3550 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
3345 snd_hda_codec_write(codec, cfg->line_out_pins[i], 0, 3551 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
3346 AC_VERB_SET_PIN_WIDGET_CONTROL, 3552 strcpy(uinfo->value.enumerated.name,
3347 present ? 0 : PIN_OUT); 3553 texts[uinfo->value.enumerated.item]);
3554 return 0;
3555}
3556
3557static int cx_automute_mode_get(struct snd_kcontrol *kcontrol,
3558 struct snd_ctl_elem_value *ucontrol)
3559{
3560 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3561 struct conexant_spec *spec = codec->spec;
3562 unsigned int val;
3563 if (!spec->auto_mute)
3564 val = 0;
3565 else if (!spec->automute_lines)
3566 val = 1;
3567 else
3568 val = 2;
3569 ucontrol->value.enumerated.item[0] = val;
3570 return 0;
3571}
3572
3573static int cx_automute_mode_put(struct snd_kcontrol *kcontrol,
3574 struct snd_ctl_elem_value *ucontrol)
3575{
3576 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3577 struct conexant_spec *spec = codec->spec;
3578
3579 switch (ucontrol->value.enumerated.item[0]) {
3580 case 0:
3581 if (!spec->auto_mute)
3582 return 0;
3583 spec->auto_mute = 0;
3584 break;
3585 case 1:
3586 if (spec->auto_mute && !spec->automute_lines)
3587 return 0;
3588 spec->auto_mute = 1;
3589 spec->automute_lines = 0;
3590 break;
3591 case 2:
3592 if (!spec->automute_hp_lo)
3593 return -EINVAL;
3594 if (spec->auto_mute && spec->automute_lines)
3595 return 0;
3596 spec->auto_mute = 1;
3597 spec->automute_lines = 1;
3598 break;
3599 default:
3600 return -EINVAL;
3348 } 3601 }
3349 for (i = 0; !present && i < cfg->line_outs; i++) 3602 cx_auto_update_speakers(codec);
3350 if (snd_hda_jack_detect(codec, cfg->line_out_pins[i])) 3603 return 1;
3351 present = 1; 3604}
3352 for (i = 0; i < cfg->speaker_outs; i++) { 3605
3353 snd_hda_codec_write(codec, cfg->speaker_pins[i], 0, 3606static const struct snd_kcontrol_new cx_automute_mode_enum[] = {
3354 AC_VERB_SET_PIN_WIDGET_CONTROL, 3607 {
3355 present ? 0 : PIN_OUT); 3608 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3609 .name = "Auto-Mute Mode",
3610 .info = cx_automute_mode_info,
3611 .get = cx_automute_mode_get,
3612 .put = cx_automute_mode_put,
3613 },
3614 { }
3615};
3616
3617static int cx_auto_mux_enum_info(struct snd_kcontrol *kcontrol,
3618 struct snd_ctl_elem_info *uinfo)
3619{
3620 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3621 struct conexant_spec *spec = codec->spec;
3622
3623 return snd_hda_input_mux_info(&spec->private_imux, uinfo);
3624}
3625
3626static int cx_auto_mux_enum_get(struct snd_kcontrol *kcontrol,
3627 struct snd_ctl_elem_value *ucontrol)
3628{
3629 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3630 struct conexant_spec *spec = codec->spec;
3631
3632 ucontrol->value.enumerated.item[0] = spec->cur_mux[0];
3633 return 0;
3634}
3635
3636/* look for the route the given pin from mux and return the index;
3637 * if do_select is set, actually select the route.
3638 */
3639static int __select_input_connection(struct hda_codec *codec, hda_nid_t mux,
3640 hda_nid_t pin, hda_nid_t *srcp,
3641 bool do_select, int depth)
3642{
3643 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
3644 int i, nums;
3645
3646 switch (get_wcaps_type(get_wcaps(codec, mux))) {
3647 case AC_WID_AUD_IN:
3648 case AC_WID_AUD_SEL:
3649 case AC_WID_AUD_MIX:
3650 break;
3651 default:
3652 return -1;
3356 } 3653 }
3654
3655 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
3656 for (i = 0; i < nums; i++)
3657 if (conn[i] == pin) {
3658 if (do_select)
3659 snd_hda_codec_write(codec, mux, 0,
3660 AC_VERB_SET_CONNECT_SEL, i);
3661 if (srcp)
3662 *srcp = mux;
3663 return i;
3664 }
3665 depth++;
3666 if (depth == 2)
3667 return -1;
3668 for (i = 0; i < nums; i++) {
3669 int ret = __select_input_connection(codec, conn[i], pin, srcp,
3670 do_select, depth);
3671 if (ret >= 0) {
3672 if (do_select)
3673 snd_hda_codec_write(codec, mux, 0,
3674 AC_VERB_SET_CONNECT_SEL, i);
3675 return i;
3676 }
3677 }
3678 return -1;
3679}
3680
3681static void select_input_connection(struct hda_codec *codec, hda_nid_t mux,
3682 hda_nid_t pin)
3683{
3684 __select_input_connection(codec, mux, pin, NULL, true, 0);
3685}
3686
3687static int get_input_connection(struct hda_codec *codec, hda_nid_t mux,
3688 hda_nid_t pin)
3689{
3690 return __select_input_connection(codec, mux, pin, NULL, false, 0);
3691}
3692
3693static int cx_auto_mux_enum_update(struct hda_codec *codec,
3694 const struct hda_input_mux *imux,
3695 unsigned int idx)
3696{
3697 struct conexant_spec *spec = codec->spec;
3698 hda_nid_t adc;
3699
3700 if (!imux->num_items)
3701 return 0;
3702 if (idx >= imux->num_items)
3703 idx = imux->num_items - 1;
3704 if (spec->cur_mux[0] == idx)
3705 return 0;
3706 adc = spec->imux_info[idx].adc;
3707 select_input_connection(codec, spec->imux_info[idx].adc,
3708 spec->imux_info[idx].pin);
3709 if (spec->cur_adc && spec->cur_adc != adc) {
3710 /* stream is running, let's swap the current ADC */
3711 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
3712 spec->cur_adc = adc;
3713 snd_hda_codec_setup_stream(codec, adc,
3714 spec->cur_adc_stream_tag, 0,
3715 spec->cur_adc_format);
3716 }
3717 spec->cur_mux[0] = idx;
3718 return 1;
3719}
3720
3721static int cx_auto_mux_enum_put(struct snd_kcontrol *kcontrol,
3722 struct snd_ctl_elem_value *ucontrol)
3723{
3724 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3725 struct conexant_spec *spec = codec->spec;
3726
3727 return cx_auto_mux_enum_update(codec, &spec->private_imux,
3728 ucontrol->value.enumerated.item[0]);
3729}
3730
3731static const struct snd_kcontrol_new cx_auto_capture_mixers[] = {
3732 {
3733 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3734 .name = "Capture Source",
3735 .info = cx_auto_mux_enum_info,
3736 .get = cx_auto_mux_enum_get,
3737 .put = cx_auto_mux_enum_put
3738 },
3739 {}
3740};
3741
3742static bool select_automic(struct hda_codec *codec, int idx, bool detect)
3743{
3744 struct conexant_spec *spec = codec->spec;
3745 if (idx < 0)
3746 return false;
3747 if (detect && !snd_hda_jack_detect(codec, spec->imux_info[idx].pin))
3748 return false;
3749 cx_auto_mux_enum_update(codec, &spec->private_imux, idx);
3750 return true;
3357} 3751}
3358 3752
3359/* automatic switch internal and external mic */ 3753/* automatic switch internal and external mic */
3360static void cx_auto_automic(struct hda_codec *codec) 3754static void cx_auto_automic(struct hda_codec *codec)
3361{ 3755{
3362 struct conexant_spec *spec = codec->spec; 3756 struct conexant_spec *spec = codec->spec;
3363 struct auto_pin_cfg *cfg = &spec->autocfg;
3364 struct hda_input_mux *imux = &spec->private_imux;
3365 int ext_idx = spec->auto_mic_ext;
3366 3757
3367 if (!spec->auto_mic) 3758 if (!spec->auto_mic)
3368 return; 3759 return;
3369 if (snd_hda_jack_detect(codec, cfg->inputs[ext_idx].pin)) { 3760 if (!select_automic(codec, spec->auto_mic_ext, true))
3370 snd_hda_codec_write(codec, spec->adc_nids[0], 0, 3761 if (!select_automic(codec, spec->auto_mic_dock, true))
3371 AC_VERB_SET_CONNECT_SEL, 3762 select_automic(codec, spec->auto_mic_int, false);
3372 imux->items[ext_idx].index);
3373 } else {
3374 snd_hda_codec_write(codec, spec->adc_nids[0], 0,
3375 AC_VERB_SET_CONNECT_SEL,
3376 imux->items[!ext_idx].index);
3377 }
3378} 3763}
3379 3764
3380static void cx_auto_unsol_event(struct hda_codec *codec, unsigned int res) 3765static void cx_auto_unsol_event(struct hda_codec *codec, unsigned int res)
@@ -3383,7 +3768,9 @@ static void cx_auto_unsol_event(struct hda_codec *codec, unsigned int res)
3383 switch (res >> 26) { 3768 switch (res >> 26) {
3384 case CONEXANT_HP_EVENT: 3769 case CONEXANT_HP_EVENT:
3385 cx_auto_hp_automute(codec); 3770 cx_auto_hp_automute(codec);
3386 snd_hda_input_jack_report(codec, nid); 3771 break;
3772 case CONEXANT_LINE_EVENT:
3773 cx_auto_line_automute(codec);
3387 break; 3774 break;
3388 case CONEXANT_MIC_EVENT: 3775 case CONEXANT_MIC_EVENT:
3389 cx_auto_automic(codec); 3776 cx_auto_automic(codec);
@@ -3392,43 +3779,45 @@ static void cx_auto_unsol_event(struct hda_codec *codec, unsigned int res)
3392 } 3779 }
3393} 3780}
3394 3781
3395/* return true if it's an internal-mic pin */
3396static int is_int_mic(struct hda_codec *codec, hda_nid_t pin)
3397{
3398 unsigned int def_conf = snd_hda_codec_get_pincfg(codec, pin);
3399 return get_defcfg_device(def_conf) == AC_JACK_MIC_IN &&
3400 snd_hda_get_input_pin_attr(def_conf) == INPUT_PIN_ATTR_INT;
3401}
3402
3403/* return true if it's an external-mic pin */
3404static int is_ext_mic(struct hda_codec *codec, hda_nid_t pin)
3405{
3406 unsigned int def_conf = snd_hda_codec_get_pincfg(codec, pin);
3407 return get_defcfg_device(def_conf) == AC_JACK_MIC_IN &&
3408 snd_hda_get_input_pin_attr(def_conf) >= INPUT_PIN_ATTR_NORMAL &&
3409 (snd_hda_query_pin_caps(codec, pin) & AC_PINCAP_PRES_DETECT);
3410}
3411
3412/* check whether the pin config is suitable for auto-mic switching; 3782/* check whether the pin config is suitable for auto-mic switching;
3413 * auto-mic is enabled only when one int-mic and one-ext mic exist 3783 * auto-mic is enabled only when one int-mic and one ext- and/or
3784 * one dock-mic exist
3414 */ 3785 */
3415static void cx_auto_check_auto_mic(struct hda_codec *codec) 3786static void cx_auto_check_auto_mic(struct hda_codec *codec)
3416{ 3787{
3417 struct conexant_spec *spec = codec->spec; 3788 struct conexant_spec *spec = codec->spec;
3418 struct auto_pin_cfg *cfg = &spec->autocfg; 3789 int pset[INPUT_PIN_ATTR_NORMAL + 1];
3790 int i;
3419 3791
3420 if (is_ext_mic(codec, cfg->inputs[0].pin) && 3792 for (i = 0; i < INPUT_PIN_ATTR_NORMAL; i++)
3421 is_int_mic(codec, cfg->inputs[1].pin)) { 3793 pset[i] = -1;
3422 spec->auto_mic = 1; 3794 for (i = 0; i < spec->private_imux.num_items; i++) {
3423 spec->auto_mic_ext = 1; 3795 hda_nid_t pin = spec->imux_info[i].pin;
3424 return; 3796 unsigned int def_conf = snd_hda_codec_get_pincfg(codec, pin);
3425 } 3797 int type, attr;
3426 if (is_int_mic(codec, cfg->inputs[1].pin) && 3798 attr = snd_hda_get_input_pin_attr(def_conf);
3427 is_ext_mic(codec, cfg->inputs[0].pin)) { 3799 if (attr == INPUT_PIN_ATTR_UNUSED)
3428 spec->auto_mic = 1; 3800 return; /* invalid entry */
3429 spec->auto_mic_ext = 0; 3801 if (attr > INPUT_PIN_ATTR_NORMAL)
3430 return; 3802 attr = INPUT_PIN_ATTR_NORMAL;
3803 if (attr != INPUT_PIN_ATTR_INT &&
3804 !is_jack_detectable(codec, pin))
3805 return; /* non-detectable pin */
3806 type = get_defcfg_device(def_conf);
3807 if (type != AC_JACK_MIC_IN &&
3808 (attr != INPUT_PIN_ATTR_DOCK || type != AC_JACK_LINE_IN))
3809 return; /* no valid input type */
3810 if (pset[attr] >= 0)
3811 return; /* already occupied */
3812 pset[attr] = i;
3431 } 3813 }
3814 if (pset[INPUT_PIN_ATTR_INT] < 0 ||
3815 (pset[INPUT_PIN_ATTR_NORMAL] < 0 && pset[INPUT_PIN_ATTR_DOCK]))
3816 return; /* no input to switch*/
3817 spec->auto_mic = 1;
3818 spec->auto_mic_ext = pset[INPUT_PIN_ATTR_NORMAL];
3819 spec->auto_mic_dock = pset[INPUT_PIN_ATTR_DOCK];
3820 spec->auto_mic_int = pset[INPUT_PIN_ATTR_INT];
3432} 3821}
3433 3822
3434static void cx_auto_parse_input(struct hda_codec *codec) 3823static void cx_auto_parse_input(struct hda_codec *codec)
@@ -3436,22 +3825,37 @@ static void cx_auto_parse_input(struct hda_codec *codec)
3436 struct conexant_spec *spec = codec->spec; 3825 struct conexant_spec *spec = codec->spec;
3437 struct auto_pin_cfg *cfg = &spec->autocfg; 3826 struct auto_pin_cfg *cfg = &spec->autocfg;
3438 struct hda_input_mux *imux; 3827 struct hda_input_mux *imux;
3439 int i; 3828 int i, j;
3440 3829
3441 imux = &spec->private_imux; 3830 imux = &spec->private_imux;
3442 for (i = 0; i < cfg->num_inputs; i++) { 3831 for (i = 0; i < cfg->num_inputs; i++) {
3443 int idx = get_connection_index(codec, spec->adc_nids[0], 3832 for (j = 0; j < spec->num_adc_nids; j++) {
3444 cfg->inputs[i].pin); 3833 hda_nid_t adc = spec->adc_nids[j];
3445 if (idx >= 0) { 3834 int idx = get_input_connection(codec, adc,
3446 const char *label; 3835 cfg->inputs[i].pin);
3447 label = hda_get_autocfg_input_label(codec, cfg, i); 3836 if (idx >= 0) {
3448 snd_hda_add_imux_item(imux, label, idx, NULL); 3837 const char *label;
3838 label = hda_get_autocfg_input_label(codec, cfg, i);
3839 spec->imux_info[imux->num_items].index = i;
3840 spec->imux_info[imux->num_items].boost = 0;
3841 spec->imux_info[imux->num_items].adc = adc;
3842 spec->imux_info[imux->num_items].pin =
3843 cfg->inputs[i].pin;
3844 snd_hda_add_imux_item(imux, label, idx, NULL);
3845 break;
3846 }
3449 } 3847 }
3450 } 3848 }
3451 if (imux->num_items == 2 && cfg->num_inputs == 2) 3849 if (imux->num_items >= 2 && cfg->num_inputs == imux->num_items)
3452 cx_auto_check_auto_mic(codec); 3850 cx_auto_check_auto_mic(codec);
3453 if (imux->num_items > 1 && !spec->auto_mic) 3851 if (imux->num_items > 1 && !spec->auto_mic) {
3454 spec->input_mux = imux; 3852 for (i = 1; i < imux->num_items; i++) {
3853 if (spec->imux_info[i].adc != spec->imux_info[0].adc) {
3854 spec->adc_switching = 1;
3855 break;
3856 }
3857 }
3858 }
3455} 3859}
3456 3860
3457/* get digital-input audio widget corresponding to the given pin */ 3861/* get digital-input audio widget corresponding to the given pin */
@@ -3517,14 +3921,15 @@ static int cx_auto_parse_auto_config(struct hda_codec *codec)
3517 return 0; 3921 return 0;
3518} 3922}
3519 3923
3520static void cx_auto_turn_on_eapd(struct hda_codec *codec, int num_pins, 3924static void cx_auto_turn_eapd(struct hda_codec *codec, int num_pins,
3521 hda_nid_t *pins) 3925 hda_nid_t *pins, bool on)
3522{ 3926{
3523 int i; 3927 int i;
3524 for (i = 0; i < num_pins; i++) { 3928 for (i = 0; i < num_pins; i++) {
3525 if (snd_hda_query_pin_caps(codec, pins[i]) & AC_PINCAP_EAPD) 3929 if (snd_hda_query_pin_caps(codec, pins[i]) & AC_PINCAP_EAPD)
3526 snd_hda_codec_write(codec, pins[i], 0, 3930 snd_hda_codec_write(codec, pins[i], 0,
3527 AC_VERB_SET_EAPD_BTLENABLE, 0x02); 3931 AC_VERB_SET_EAPD_BTLENABLE,
3932 on ? 0x02 : 0);
3528 } 3933 }
3529} 3934}
3530 3935
@@ -3537,6 +3942,34 @@ static void select_connection(struct hda_codec *codec, hda_nid_t pin,
3537 AC_VERB_SET_CONNECT_SEL, idx); 3942 AC_VERB_SET_CONNECT_SEL, idx);
3538} 3943}
3539 3944
3945static void mute_outputs(struct hda_codec *codec, int num_nids,
3946 const hda_nid_t *nids)
3947{
3948 int i, val;
3949
3950 for (i = 0; i < num_nids; i++) {
3951 hda_nid_t nid = nids[i];
3952 if (!(get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
3953 continue;
3954 if (query_amp_caps(codec, nid, HDA_OUTPUT) & AC_AMPCAP_MUTE)
3955 val = AMP_OUT_MUTE;
3956 else
3957 val = AMP_OUT_ZERO;
3958 snd_hda_codec_write(codec, nid, 0,
3959 AC_VERB_SET_AMP_GAIN_MUTE, val);
3960 }
3961}
3962
3963static void enable_unsol_pins(struct hda_codec *codec, int num_pins,
3964 hda_nid_t *pins, unsigned int tag)
3965{
3966 int i;
3967 for (i = 0; i < num_pins; i++)
3968 snd_hda_codec_write(codec, pins[i], 0,
3969 AC_VERB_SET_UNSOLICITED_ENABLE,
3970 AC_USRSP_EN | tag);
3971}
3972
3540static void cx_auto_init_output(struct hda_codec *codec) 3973static void cx_auto_init_output(struct hda_codec *codec)
3541{ 3974{
3542 struct conexant_spec *spec = codec->spec; 3975 struct conexant_spec *spec = codec->spec;
@@ -3544,51 +3977,53 @@ static void cx_auto_init_output(struct hda_codec *codec)
3544 hda_nid_t nid; 3977 hda_nid_t nid;
3545 int i; 3978 int i;
3546 3979
3547 for (i = 0; i < spec->multiout.num_dacs; i++) 3980 mute_outputs(codec, spec->multiout.num_dacs, spec->multiout.dac_nids);
3548 snd_hda_codec_write(codec, spec->multiout.dac_nids[i], 0,
3549 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3550
3551 for (i = 0; i < cfg->hp_outs; i++) 3981 for (i = 0; i < cfg->hp_outs; i++)
3552 snd_hda_codec_write(codec, cfg->hp_pins[i], 0, 3982 snd_hda_codec_write(codec, cfg->hp_pins[i], 0,
3553 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP); 3983 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
3554 if (spec->auto_mute) { 3984 mute_outputs(codec, cfg->hp_outs, cfg->hp_pins);
3555 for (i = 0; i < cfg->hp_outs; i++) { 3985 mute_outputs(codec, cfg->line_outs, cfg->line_out_pins);
3556 snd_hda_codec_write(codec, cfg->hp_pins[i], 0, 3986 mute_outputs(codec, cfg->speaker_outs, cfg->speaker_pins);
3557 AC_VERB_SET_UNSOLICITED_ENABLE,
3558 AC_USRSP_EN | CONEXANT_HP_EVENT);
3559 }
3560 cx_auto_hp_automute(codec);
3561 } else {
3562 for (i = 0; i < cfg->line_outs; i++)
3563 snd_hda_codec_write(codec, cfg->line_out_pins[i], 0,
3564 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3565 for (i = 0; i < cfg->speaker_outs; i++)
3566 snd_hda_codec_write(codec, cfg->speaker_pins[i], 0,
3567 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3568 }
3569
3570 for (i = 0; i < spec->dac_info_filled; i++) { 3987 for (i = 0; i < spec->dac_info_filled; i++) {
3571 nid = spec->dac_info[i].dac; 3988 nid = spec->dac_info[i].dac;
3572 if (!nid) 3989 if (!nid)
3573 nid = spec->multiout.dac_nids[0]; 3990 nid = spec->multiout.dac_nids[0];
3574 select_connection(codec, spec->dac_info[i].pin, nid); 3991 select_connection(codec, spec->dac_info[i].pin, nid);
3575 } 3992 }
3576 3993 if (spec->auto_mute) {
3577 /* turn on EAPD */ 3994 enable_unsol_pins(codec, cfg->hp_outs, cfg->hp_pins,
3578 cx_auto_turn_on_eapd(codec, cfg->line_outs, cfg->line_out_pins); 3995 CONEXANT_HP_EVENT);
3579 cx_auto_turn_on_eapd(codec, cfg->hp_outs, cfg->hp_pins); 3996 spec->hp_present = detect_jacks(codec, cfg->hp_outs,
3580 cx_auto_turn_on_eapd(codec, cfg->speaker_outs, cfg->speaker_pins); 3997 cfg->hp_pins);
3998 if (spec->detect_line) {
3999 enable_unsol_pins(codec, cfg->line_outs,
4000 cfg->line_out_pins,
4001 CONEXANT_LINE_EVENT);
4002 spec->line_present =
4003 detect_jacks(codec, cfg->line_outs,
4004 cfg->line_out_pins);
4005 }
4006 }
4007 cx_auto_update_speakers(codec);
3581} 4008}
3582 4009
3583static void cx_auto_init_input(struct hda_codec *codec) 4010static void cx_auto_init_input(struct hda_codec *codec)
3584{ 4011{
3585 struct conexant_spec *spec = codec->spec; 4012 struct conexant_spec *spec = codec->spec;
3586 struct auto_pin_cfg *cfg = &spec->autocfg; 4013 struct auto_pin_cfg *cfg = &spec->autocfg;
3587 int i; 4014 int i, val;
3588 4015
3589 for (i = 0; i < spec->num_adc_nids; i++) 4016 for (i = 0; i < spec->num_adc_nids; i++) {
3590 snd_hda_codec_write(codec, spec->adc_nids[i], 0, 4017 hda_nid_t nid = spec->adc_nids[i];
3591 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)); 4018 if (!(get_wcaps(codec, nid) & AC_WCAP_IN_AMP))
4019 continue;
4020 if (query_amp_caps(codec, nid, HDA_INPUT) & AC_AMPCAP_MUTE)
4021 val = AMP_IN_MUTE(0);
4022 else
4023 val = AMP_IN_UNMUTE(0);
4024 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4025 val);
4026 }
3592 4027
3593 for (i = 0; i < cfg->num_inputs; i++) { 4028 for (i = 0; i < cfg->num_inputs; i++) {
3594 unsigned int type; 4029 unsigned int type;
@@ -3601,17 +4036,22 @@ static void cx_auto_init_input(struct hda_codec *codec)
3601 } 4036 }
3602 4037
3603 if (spec->auto_mic) { 4038 if (spec->auto_mic) {
3604 int ext_idx = spec->auto_mic_ext; 4039 if (spec->auto_mic_ext >= 0) {
3605 snd_hda_codec_write(codec, cfg->inputs[ext_idx].pin, 0, 4040 snd_hda_codec_write(codec,
3606 AC_VERB_SET_UNSOLICITED_ENABLE, 4041 cfg->inputs[spec->auto_mic_ext].pin, 0,
3607 AC_USRSP_EN | CONEXANT_MIC_EVENT); 4042 AC_VERB_SET_UNSOLICITED_ENABLE,
4043 AC_USRSP_EN | CONEXANT_MIC_EVENT);
4044 }
4045 if (spec->auto_mic_dock >= 0) {
4046 snd_hda_codec_write(codec,
4047 cfg->inputs[spec->auto_mic_dock].pin, 0,
4048 AC_VERB_SET_UNSOLICITED_ENABLE,
4049 AC_USRSP_EN | CONEXANT_MIC_EVENT);
4050 }
3608 cx_auto_automic(codec); 4051 cx_auto_automic(codec);
3609 } else { 4052 } else {
3610 for (i = 0; i < spec->num_adc_nids; i++) { 4053 select_input_connection(codec, spec->imux_info[0].adc,
3611 snd_hda_codec_write(codec, spec->adc_nids[i], 0, 4054 spec->imux_info[0].pin);
3612 AC_VERB_SET_CONNECT_SEL,
3613 spec->private_imux.items[0].index);
3614 }
3615 } 4055 }
3616} 4056}
3617 4057
@@ -3646,7 +4086,7 @@ static int cx_auto_add_volume_idx(struct hda_codec *codec, const char *basename,
3646 HDA_CODEC_VOLUME(name, 0, 0, 0), 4086 HDA_CODEC_VOLUME(name, 0, 0, 0),
3647 HDA_CODEC_MUTE(name, 0, 0, 0), 4087 HDA_CODEC_MUTE(name, 0, 0, 0),
3648 }; 4088 };
3649 static char *sfx[2] = { "Volume", "Switch" }; 4089 static const char * const sfx[2] = { "Volume", "Switch" };
3650 int i, err; 4090 int i, err;
3651 4091
3652 for (i = 0; i < 2; i++) { 4092 for (i = 0; i < 2; i++) {
@@ -3674,6 +4114,19 @@ static int cx_auto_add_volume_idx(struct hda_codec *codec, const char *basename,
3674#define cx_auto_add_pb_volume(codec, nid, str, idx) \ 4114#define cx_auto_add_pb_volume(codec, nid, str, idx) \
3675 cx_auto_add_volume(codec, str, " Playback", idx, nid, HDA_OUTPUT) 4115 cx_auto_add_volume(codec, str, " Playback", idx, nid, HDA_OUTPUT)
3676 4116
4117static int try_add_pb_volume(struct hda_codec *codec, hda_nid_t dac,
4118 hda_nid_t pin, const char *name, int idx)
4119{
4120 unsigned int caps;
4121 caps = query_amp_caps(codec, dac, HDA_OUTPUT);
4122 if (caps & AC_AMPCAP_NUM_STEPS)
4123 return cx_auto_add_pb_volume(codec, dac, name, idx);
4124 caps = query_amp_caps(codec, pin, HDA_OUTPUT);
4125 if (caps & AC_AMPCAP_NUM_STEPS)
4126 return cx_auto_add_pb_volume(codec, pin, name, idx);
4127 return 0;
4128}
4129
3677static int cx_auto_build_output_controls(struct hda_codec *codec) 4130static int cx_auto_build_output_controls(struct hda_codec *codec)
3678{ 4131{
3679 struct conexant_spec *spec = codec->spec; 4132 struct conexant_spec *spec = codec->spec;
@@ -3682,8 +4135,10 @@ static int cx_auto_build_output_controls(struct hda_codec *codec)
3682 static const char * const texts[3] = { "Front", "Surround", "CLFE" }; 4135 static const char * const texts[3] = { "Front", "Surround", "CLFE" };
3683 4136
3684 if (spec->dac_info_filled == 1) 4137 if (spec->dac_info_filled == 1)
3685 return cx_auto_add_pb_volume(codec, spec->dac_info[0].dac, 4138 return try_add_pb_volume(codec, spec->dac_info[0].dac,
3686 "Master", 0); 4139 spec->dac_info[0].pin,
4140 "Master", 0);
4141
3687 for (i = 0; i < spec->dac_info_filled; i++) { 4142 for (i = 0; i < spec->dac_info_filled; i++) {
3688 const char *label; 4143 const char *label;
3689 int idx, type; 4144 int idx, type;
@@ -3707,74 +4162,123 @@ static int cx_auto_build_output_controls(struct hda_codec *codec)
3707 idx = num_spk++; 4162 idx = num_spk++;
3708 break; 4163 break;
3709 } 4164 }
3710 err = cx_auto_add_pb_volume(codec, spec->dac_info[i].dac, 4165 err = try_add_pb_volume(codec, spec->dac_info[i].dac,
3711 label, idx); 4166 spec->dac_info[i].pin,
4167 label, idx);
4168 if (err < 0)
4169 return err;
4170 }
4171
4172 if (spec->auto_mute) {
4173 err = snd_hda_add_new_ctls(codec, cx_automute_mode_enum);
3712 if (err < 0) 4174 if (err < 0)
3713 return err; 4175 return err;
3714 } 4176 }
4177
4178 return 0;
4179}
4180
4181static int cx_auto_add_capture_volume(struct hda_codec *codec, hda_nid_t nid,
4182 const char *label, const char *pfx,
4183 int cidx)
4184{
4185 struct conexant_spec *spec = codec->spec;
4186 int i;
4187
4188 for (i = 0; i < spec->num_adc_nids; i++) {
4189 hda_nid_t adc_nid = spec->adc_nids[i];
4190 int idx = get_input_connection(codec, adc_nid, nid);
4191 if (idx < 0)
4192 continue;
4193 return cx_auto_add_volume_idx(codec, label, pfx,
4194 cidx, adc_nid, HDA_INPUT, idx);
4195 }
4196 return 0;
4197}
4198
4199static int cx_auto_add_boost_volume(struct hda_codec *codec, int idx,
4200 const char *label, int cidx)
4201{
4202 struct conexant_spec *spec = codec->spec;
4203 hda_nid_t mux, nid;
4204 int i, con;
4205
4206 nid = spec->imux_info[idx].pin;
4207 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
4208 return cx_auto_add_volume(codec, label, " Boost", cidx,
4209 nid, HDA_INPUT);
4210 con = __select_input_connection(codec, spec->imux_info[idx].adc, nid,
4211 &mux, false, 0);
4212 if (con < 0)
4213 return 0;
4214 for (i = 0; i < idx; i++) {
4215 if (spec->imux_info[i].boost == mux)
4216 return 0; /* already present */
4217 }
4218
4219 if (get_wcaps(codec, mux) & AC_WCAP_OUT_AMP) {
4220 spec->imux_info[idx].boost = mux;
4221 return cx_auto_add_volume(codec, label, " Boost", 0,
4222 mux, HDA_OUTPUT);
4223 }
3715 return 0; 4224 return 0;
3716} 4225}
3717 4226
3718static int cx_auto_build_input_controls(struct hda_codec *codec) 4227static int cx_auto_build_input_controls(struct hda_codec *codec)
3719{ 4228{
3720 struct conexant_spec *spec = codec->spec; 4229 struct conexant_spec *spec = codec->spec;
3721 struct auto_pin_cfg *cfg = &spec->autocfg; 4230 struct hda_input_mux *imux = &spec->private_imux;
3722 static const char *prev_label; 4231 const char *prev_label;
3723 int i, err, cidx, conn_len; 4232 int input_conn[HDA_MAX_NUM_INPUTS];
3724 hda_nid_t conn[HDA_MAX_CONNECTIONS]; 4233 int i, err, cidx;
3725 4234 int multi_connection;
3726 int multi_adc_volume = 0; /* If the ADC nid has several input volumes */ 4235
3727 int adc_nid = spec->adc_nids[0]; 4236 multi_connection = 0;
3728 4237 for (i = 0; i < imux->num_items; i++) {
3729 conn_len = snd_hda_get_connections(codec, adc_nid, conn, 4238 cidx = get_input_connection(codec, spec->imux_info[i].adc,
3730 HDA_MAX_CONNECTIONS); 4239 spec->imux_info[i].pin);
3731 if (conn_len < 0) 4240 input_conn[i] = (spec->imux_info[i].adc << 8) | cidx;
3732 return conn_len; 4241 if (i > 0 && input_conn[i] != input_conn[0])
3733 4242 multi_connection = 1;
3734 multi_adc_volume = cfg->num_inputs > 1 && conn_len > 1;
3735 if (!multi_adc_volume) {
3736 err = cx_auto_add_volume(codec, "Capture", "", 0, adc_nid,
3737 HDA_INPUT);
3738 if (err < 0)
3739 return err;
3740 } 4243 }
3741 4244
3742 prev_label = NULL; 4245 prev_label = NULL;
3743 cidx = 0; 4246 cidx = 0;
3744 for (i = 0; i < cfg->num_inputs; i++) { 4247 for (i = 0; i < imux->num_items; i++) {
3745 hda_nid_t nid = cfg->inputs[i].pin; 4248 hda_nid_t nid = spec->imux_info[i].pin;
3746 const char *label; 4249 const char *label;
3747 int j;
3748 int pin_amp = get_wcaps(codec, nid) & AC_WCAP_IN_AMP;
3749 if (!pin_amp && !multi_adc_volume)
3750 continue;
3751 4250
3752 label = hda_get_autocfg_input_label(codec, cfg, i); 4251 label = hda_get_autocfg_input_label(codec, &spec->autocfg,
4252 spec->imux_info[i].index);
3753 if (label == prev_label) 4253 if (label == prev_label)
3754 cidx++; 4254 cidx++;
3755 else 4255 else
3756 cidx = 0; 4256 cidx = 0;
3757 prev_label = label; 4257 prev_label = label;
3758 4258
3759 if (pin_amp) { 4259 err = cx_auto_add_boost_volume(codec, i, label, cidx);
3760 err = cx_auto_add_volume(codec, label, " Boost", cidx, 4260 if (err < 0)
3761 nid, HDA_INPUT); 4261 return err;
3762 if (err < 0)
3763 return err;
3764 }
3765 4262
3766 if (!multi_adc_volume) 4263 if (!multi_connection) {
3767 continue; 4264 if (i > 0)
3768 for (j = 0; j < conn_len; j++) { 4265 continue;
3769 if (conn[j] == nid) { 4266 err = cx_auto_add_capture_volume(codec, nid,
3770 err = cx_auto_add_volume_idx(codec, label, 4267 "Capture", "", cidx);
3771 " Capture", cidx, adc_nid, HDA_INPUT, j); 4268 } else {
3772 if (err < 0) 4269 err = cx_auto_add_capture_volume(codec, nid,
3773 return err; 4270 label, " Capture", cidx);
3774 break;
3775 }
3776 } 4271 }
4272 if (err < 0)
4273 return err;
3777 } 4274 }
4275
4276 if (spec->private_imux.num_items > 1 && !spec->auto_mic) {
4277 err = snd_hda_add_new_ctls(codec, cx_auto_capture_mixers);
4278 if (err < 0)
4279 return err;
4280 }
4281
3778 return 0; 4282 return 0;
3779} 4283}
3780 4284
@@ -3791,7 +4295,29 @@ static int cx_auto_build_controls(struct hda_codec *codec)
3791 return conexant_build_controls(codec); 4295 return conexant_build_controls(codec);
3792} 4296}
3793 4297
3794static struct hda_codec_ops cx_auto_patch_ops = { 4298static int cx_auto_search_adcs(struct hda_codec *codec)
4299{
4300 struct conexant_spec *spec = codec->spec;
4301 hda_nid_t nid, end_nid;
4302
4303 end_nid = codec->start_nid + codec->num_nodes;
4304 for (nid = codec->start_nid; nid < end_nid; nid++) {
4305 unsigned int caps = get_wcaps(codec, nid);
4306 if (get_wcaps_type(caps) != AC_WID_AUD_IN)
4307 continue;
4308 if (caps & AC_WCAP_DIGITAL)
4309 continue;
4310 if (snd_BUG_ON(spec->num_adc_nids >=
4311 ARRAY_SIZE(spec->private_adc_nids)))
4312 break;
4313 spec->private_adc_nids[spec->num_adc_nids++] = nid;
4314 }
4315 spec->adc_nids = spec->private_adc_nids;
4316 return 0;
4317}
4318
4319
4320static const struct hda_codec_ops cx_auto_patch_ops = {
3795 .build_controls = cx_auto_build_controls, 4321 .build_controls = cx_auto_build_controls,
3796 .build_pcms = conexant_build_pcms, 4322 .build_pcms = conexant_build_pcms,
3797 .init = cx_auto_init, 4323 .init = cx_auto_init,
@@ -3808,19 +4334,24 @@ static int patch_conexant_auto(struct hda_codec *codec)
3808 struct conexant_spec *spec; 4334 struct conexant_spec *spec;
3809 int err; 4335 int err;
3810 4336
4337 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4338 codec->chip_name);
4339
3811 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 4340 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3812 if (!spec) 4341 if (!spec)
3813 return -ENOMEM; 4342 return -ENOMEM;
3814 codec->spec = spec; 4343 codec->spec = spec;
3815 spec->adc_nids = cx_auto_adc_nids; 4344 codec->pin_amp_workaround = 1;
3816 spec->num_adc_nids = ARRAY_SIZE(cx_auto_adc_nids); 4345 err = cx_auto_search_adcs(codec);
3817 spec->capsrc_nids = spec->adc_nids; 4346 if (err < 0)
4347 return err;
3818 err = cx_auto_parse_auto_config(codec); 4348 err = cx_auto_parse_auto_config(codec);
3819 if (err < 0) { 4349 if (err < 0) {
3820 kfree(codec->spec); 4350 kfree(codec->spec);
3821 codec->spec = NULL; 4351 codec->spec = NULL;
3822 return err; 4352 return err;
3823 } 4353 }
4354 spec->capture_stream = &cx_auto_pcm_analog_capture;
3824 codec->patch_ops = cx_auto_patch_ops; 4355 codec->patch_ops = cx_auto_patch_ops;
3825 if (spec->beep_amp) 4356 if (spec->beep_amp)
3826 snd_hda_attach_beep_device(codec, spec->beep_amp); 4357 snd_hda_attach_beep_device(codec, spec->beep_amp);
@@ -3830,7 +4361,7 @@ static int patch_conexant_auto(struct hda_codec *codec)
3830/* 4361/*
3831 */ 4362 */
3832 4363
3833static struct hda_codec_preset snd_hda_preset_conexant[] = { 4364static const struct hda_codec_preset snd_hda_preset_conexant[] = {
3834 { .id = 0x14f15045, .name = "CX20549 (Venice)", 4365 { .id = 0x14f15045, .name = "CX20549 (Venice)",
3835 .patch = patch_cxt5045 }, 4366 .patch = patch_cxt5045 },
3836 { .id = 0x14f15047, .name = "CX20551 (Waikiki)", 4367 { .id = 0x14f15047, .name = "CX20551 (Waikiki)",