diff options
author | Takashi Iwai <tiwai@suse.de> | 2013-01-23 02:34:12 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2013-01-23 02:34:12 -0500 |
commit | 2cf215bfaa01384374291a118c8152ab18a55a63 (patch) | |
tree | f0020c78288344f709596ede3a7e4195cfffdff7 /sound/pci/hda/patch_conexant.c | |
parent | e152f18027552eb34006b35347e72bc805783027 (diff) | |
parent | 657e1b931d42882cb0a59b599247bef696c22406 (diff) |
Merge branch 'topic/hda-gen-parser' into for-next
This is a merge of really big changes: the generic parser is heavily
enhanced for handling all cases, based on the former Realtek codec
driver code. And all codec drivers except for a few ones (CA0132,
HDMI and modem) have been converted to use the new generic driver.
Conflicts:
sound/pci/hda/patch_realtek.c
Diffstat (limited to 'sound/pci/hda/patch_conexant.c')
-rw-r--r-- | sound/pci/hda/patch_conexant.c | 1375 |
1 files changed, 100 insertions, 1275 deletions
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 009b77a693cf..d98d470b0f26 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -33,6 +33,9 @@ | |||
33 | #include "hda_auto_parser.h" | 33 | #include "hda_auto_parser.h" |
34 | #include "hda_beep.h" | 34 | #include "hda_beep.h" |
35 | #include "hda_jack.h" | 35 | #include "hda_jack.h" |
36 | #include "hda_generic.h" | ||
37 | |||
38 | #define ENABLE_CXT_STATIC_QUIRKS | ||
36 | 39 | ||
37 | #define CXT_PIN_DIR_IN 0x00 | 40 | #define CXT_PIN_DIR_IN 0x00 |
38 | #define CXT_PIN_DIR_OUT 0x01 | 41 | #define CXT_PIN_DIR_OUT 0x01 |
@@ -53,27 +56,19 @@ | |||
53 | #define AUTO_MIC_PORTB (1 << 1) | 56 | #define AUTO_MIC_PORTB (1 << 1) |
54 | #define AUTO_MIC_PORTC (1 << 2) | 57 | #define AUTO_MIC_PORTC (1 << 2) |
55 | 58 | ||
56 | struct pin_dac_pair { | ||
57 | hda_nid_t pin; | ||
58 | hda_nid_t dac; | ||
59 | int type; | ||
60 | }; | ||
61 | |||
62 | struct imux_info { | ||
63 | hda_nid_t pin; /* input pin NID */ | ||
64 | hda_nid_t adc; /* connected ADC NID */ | ||
65 | hda_nid_t boost; /* optional boost volume NID */ | ||
66 | int index; /* corresponding to autocfg.input */ | ||
67 | }; | ||
68 | |||
69 | struct conexant_spec { | 59 | struct conexant_spec { |
70 | struct hda_gen_spec gen; | 60 | struct hda_gen_spec gen; |
71 | 61 | ||
62 | unsigned int beep_amp; | ||
63 | |||
64 | /* extra EAPD pins */ | ||
65 | unsigned int num_eapds; | ||
66 | hda_nid_t eapds[4]; | ||
67 | |||
68 | #ifdef ENABLE_CXT_STATIC_QUIRKS | ||
72 | const struct snd_kcontrol_new *mixers[5]; | 69 | const struct snd_kcontrol_new *mixers[5]; |
73 | int num_mixers; | 70 | int num_mixers; |
74 | hda_nid_t vmaster_nid; | 71 | hda_nid_t vmaster_nid; |
75 | struct hda_vmaster_mute_hook vmaster_mute; | ||
76 | bool vmaster_mute_led; | ||
77 | 72 | ||
78 | const struct hda_verb *init_verbs[5]; /* initialization verbs | 73 | const struct hda_verb *init_verbs[5]; /* initialization verbs |
79 | * don't forget NULL | 74 | * don't forget NULL |
@@ -90,11 +85,6 @@ struct conexant_spec { | |||
90 | unsigned int hp_present; | 85 | unsigned int hp_present; |
91 | unsigned int line_present; | 86 | unsigned int line_present; |
92 | unsigned int auto_mic; | 87 | unsigned int auto_mic; |
93 | int auto_mic_ext; /* imux_pins[] index for ext mic */ | ||
94 | int auto_mic_dock; /* imux_pins[] index for dock mic */ | ||
95 | int auto_mic_int; /* imux_pins[] index for int mic */ | ||
96 | unsigned int need_dac_fix; | ||
97 | hda_nid_t slave_dig_outs[2]; | ||
98 | 88 | ||
99 | /* capture */ | 89 | /* capture */ |
100 | unsigned int num_adc_nids; | 90 | unsigned int num_adc_nids; |
@@ -122,30 +112,13 @@ struct conexant_spec { | |||
122 | 112 | ||
123 | unsigned int spdif_route; | 113 | unsigned int spdif_route; |
124 | 114 | ||
125 | /* dynamic controls, init_verbs and input_mux */ | ||
126 | struct auto_pin_cfg autocfg; | ||
127 | struct hda_input_mux private_imux; | ||
128 | struct imux_info imux_info[HDA_MAX_NUM_INPUTS]; | ||
129 | hda_nid_t private_adc_nids[HDA_MAX_NUM_INPUTS]; | ||
130 | hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; | ||
131 | struct pin_dac_pair dac_info[8]; | ||
132 | int dac_info_filled; | ||
133 | |||
134 | unsigned int port_d_mode; | 115 | unsigned int port_d_mode; |
135 | unsigned int auto_mute:1; /* used in auto-parser */ | ||
136 | unsigned int detect_line:1; /* Line-out detection enabled */ | ||
137 | unsigned int automute_lines:1; /* automute line-out as well */ | ||
138 | unsigned int automute_hp_lo:1; /* both HP and LO available */ | ||
139 | unsigned int dell_automute:1; | 116 | unsigned int dell_automute:1; |
140 | unsigned int dell_vostro:1; | 117 | unsigned int dell_vostro:1; |
141 | unsigned int ideapad:1; | 118 | unsigned int ideapad:1; |
142 | unsigned int thinkpad:1; | 119 | unsigned int thinkpad:1; |
143 | unsigned int hp_laptop:1; | 120 | unsigned int hp_laptop:1; |
144 | unsigned int asus:1; | 121 | unsigned int asus:1; |
145 | unsigned int pin_eapd_ctrls:1; | ||
146 | unsigned int fixup_stereo_dmic:1; | ||
147 | |||
148 | unsigned int adc_switching:1; | ||
149 | 122 | ||
150 | unsigned int ext_mic_present; | 123 | unsigned int ext_mic_present; |
151 | unsigned int recording; | 124 | unsigned int recording; |
@@ -161,14 +134,48 @@ struct conexant_spec { | |||
161 | unsigned int dc_enable; | 134 | unsigned int dc_enable; |
162 | unsigned int dc_input_bias; /* offset into cxt5066_olpc_dc_bias */ | 135 | unsigned int dc_input_bias; /* offset into cxt5066_olpc_dc_bias */ |
163 | unsigned int mic_boost; /* offset into cxt5066_analog_mic_boost */ | 136 | unsigned int mic_boost; /* offset into cxt5066_analog_mic_boost */ |
137 | #endif /* ENABLE_CXT_STATIC_QUIRKS */ | ||
138 | }; | ||
164 | 139 | ||
165 | unsigned int beep_amp; | ||
166 | 140 | ||
167 | /* extra EAPD pins */ | 141 | #ifdef CONFIG_SND_HDA_INPUT_BEEP |
168 | unsigned int num_eapds; | 142 | #define set_beep_amp(spec, nid, idx, dir) \ |
169 | hda_nid_t eapds[4]; | 143 | ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir)) |
144 | /* additional beep mixers; the actual parameters are overwritten at build */ | ||
145 | static const struct snd_kcontrol_new cxt_beep_mixer[] = { | ||
146 | HDA_CODEC_VOLUME_MONO("Beep Playback Volume", 0, 1, 0, HDA_OUTPUT), | ||
147 | HDA_CODEC_MUTE_BEEP_MONO("Beep Playback Switch", 0, 1, 0, HDA_OUTPUT), | ||
148 | { } /* end */ | ||
170 | }; | 149 | }; |
171 | 150 | ||
151 | /* create beep controls if needed */ | ||
152 | static int add_beep_ctls(struct hda_codec *codec) | ||
153 | { | ||
154 | struct conexant_spec *spec = codec->spec; | ||
155 | int err; | ||
156 | |||
157 | if (spec->beep_amp) { | ||
158 | const struct snd_kcontrol_new *knew; | ||
159 | for (knew = cxt_beep_mixer; knew->name; knew++) { | ||
160 | struct snd_kcontrol *kctl; | ||
161 | kctl = snd_ctl_new1(knew, codec); | ||
162 | if (!kctl) | ||
163 | return -ENOMEM; | ||
164 | kctl->private_value = spec->beep_amp; | ||
165 | err = snd_hda_ctl_add(codec, 0, kctl); | ||
166 | if (err < 0) | ||
167 | return err; | ||
168 | } | ||
169 | } | ||
170 | return 0; | ||
171 | } | ||
172 | #else | ||
173 | #define set_beep_amp(spec, nid, idx, dir) /* NOP */ | ||
174 | #define add_beep_ctls(codec) 0 | ||
175 | #endif | ||
176 | |||
177 | |||
178 | #ifdef ENABLE_CXT_STATIC_QUIRKS | ||
172 | static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo, | 179 | static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo, |
173 | struct hda_codec *codec, | 180 | struct hda_codec *codec, |
174 | struct snd_pcm_substream *substream) | 181 | struct snd_pcm_substream *substream) |
@@ -337,8 +344,6 @@ static const struct hda_pcm_stream cx5051_pcm_analog_capture = { | |||
337 | }, | 344 | }, |
338 | }; | 345 | }; |
339 | 346 | ||
340 | static bool is_2_1_speaker(struct conexant_spec *spec); | ||
341 | |||
342 | static int conexant_build_pcms(struct hda_codec *codec) | 347 | static int conexant_build_pcms(struct hda_codec *codec) |
343 | { | 348 | { |
344 | struct conexant_spec *spec = codec->spec; | 349 | struct conexant_spec *spec = codec->spec; |
@@ -353,9 +358,6 @@ static int conexant_build_pcms(struct hda_codec *codec) | |||
353 | spec->multiout.max_channels; | 358 | spec->multiout.max_channels; |
354 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = | 359 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = |
355 | spec->multiout.dac_nids[0]; | 360 | spec->multiout.dac_nids[0]; |
356 | if (is_2_1_speaker(spec)) | ||
357 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].chmap = | ||
358 | snd_pcm_2_1_chmaps; | ||
359 | if (spec->capture_stream) | 361 | if (spec->capture_stream) |
360 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = *spec->capture_stream; | 362 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = *spec->capture_stream; |
361 | else { | 363 | else { |
@@ -386,8 +388,6 @@ static int conexant_build_pcms(struct hda_codec *codec) | |||
386 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = | 388 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = |
387 | spec->dig_in_nid; | 389 | spec->dig_in_nid; |
388 | } | 390 | } |
389 | if (spec->slave_dig_outs[0]) | ||
390 | codec->slave_dig_outs = spec->slave_dig_outs; | ||
391 | } | 391 | } |
392 | 392 | ||
393 | return 0; | 393 | return 0; |
@@ -451,7 +451,6 @@ static int conexant_init(struct hda_codec *codec) | |||
451 | static void conexant_free(struct hda_codec *codec) | 451 | static void conexant_free(struct hda_codec *codec) |
452 | { | 452 | { |
453 | struct conexant_spec *spec = codec->spec; | 453 | struct conexant_spec *spec = codec->spec; |
454 | snd_hda_gen_free(&spec->gen); | ||
455 | snd_hda_detach_beep_device(codec); | 454 | snd_hda_detach_beep_device(codec); |
456 | kfree(spec); | 455 | kfree(spec); |
457 | } | 456 | } |
@@ -467,15 +466,6 @@ static const struct snd_kcontrol_new cxt_capture_mixers[] = { | |||
467 | {} | 466 | {} |
468 | }; | 467 | }; |
469 | 468 | ||
470 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | ||
471 | /* additional beep mixers; the actual parameters are overwritten at build */ | ||
472 | static const struct snd_kcontrol_new cxt_beep_mixer[] = { | ||
473 | HDA_CODEC_VOLUME_MONO("Beep Playback Volume", 0, 1, 0, HDA_OUTPUT), | ||
474 | HDA_CODEC_MUTE_BEEP_MONO("Beep Playback Switch", 0, 1, 0, HDA_OUTPUT), | ||
475 | { } /* end */ | ||
476 | }; | ||
477 | #endif | ||
478 | |||
479 | static const char * const slave_pfxs[] = { | 469 | static const char * const slave_pfxs[] = { |
480 | "Headphone", "Speaker", "Bass Speaker", "Front", "Surround", "CLFE", | 470 | "Headphone", "Speaker", "Bass Speaker", "Front", "Surround", "CLFE", |
481 | NULL | 471 | NULL |
@@ -524,10 +514,9 @@ static int conexant_build_controls(struct hda_codec *codec) | |||
524 | } | 514 | } |
525 | if (spec->vmaster_nid && | 515 | if (spec->vmaster_nid && |
526 | !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { | 516 | !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { |
527 | err = __snd_hda_add_vmaster(codec, "Master Playback Switch", | 517 | err = snd_hda_add_vmaster(codec, "Master Playback Switch", |
528 | NULL, slave_pfxs, | 518 | NULL, slave_pfxs, |
529 | "Playback Switch", true, | 519 | "Playback Switch"); |
530 | &spec->vmaster_mute.sw_kctl); | ||
531 | if (err < 0) | 520 | if (err < 0) |
532 | return err; | 521 | return err; |
533 | } | 522 | } |
@@ -538,22 +527,9 @@ static int conexant_build_controls(struct hda_codec *codec) | |||
538 | return err; | 527 | return err; |
539 | } | 528 | } |
540 | 529 | ||
541 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | 530 | err = add_beep_ctls(codec); |
542 | /* create beep controls if needed */ | 531 | if (err < 0) |
543 | if (spec->beep_amp) { | 532 | return err; |
544 | const struct snd_kcontrol_new *knew; | ||
545 | for (knew = cxt_beep_mixer; knew->name; knew++) { | ||
546 | struct snd_kcontrol *kctl; | ||
547 | kctl = snd_ctl_new1(knew, codec); | ||
548 | if (!kctl) | ||
549 | return -ENOMEM; | ||
550 | kctl->private_value = spec->beep_amp; | ||
551 | err = snd_hda_ctl_add(codec, 0, kctl); | ||
552 | if (err < 0) | ||
553 | return err; | ||
554 | } | ||
555 | } | ||
556 | #endif | ||
557 | 533 | ||
558 | return 0; | 534 | return 0; |
559 | } | 535 | } |
@@ -566,13 +542,6 @@ static const struct hda_codec_ops conexant_patch_ops = { | |||
566 | .set_power_state = conexant_set_power, | 542 | .set_power_state = conexant_set_power, |
567 | }; | 543 | }; |
568 | 544 | ||
569 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | ||
570 | #define set_beep_amp(spec, nid, idx, dir) \ | ||
571 | ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir)) | ||
572 | #else | ||
573 | #define set_beep_amp(spec, nid, idx, dir) /* NOP */ | ||
574 | #endif | ||
575 | |||
576 | static int patch_conexant_auto(struct hda_codec *codec); | 545 | static int patch_conexant_auto(struct hda_codec *codec); |
577 | /* | 546 | /* |
578 | * EAPD control | 547 | * EAPD control |
@@ -656,8 +625,6 @@ static int conexant_ch_mode_put(struct snd_kcontrol *kcontrol, | |||
656 | int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode, | 625 | int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode, |
657 | spec->num_channel_mode, | 626 | spec->num_channel_mode, |
658 | &spec->multiout.max_channels); | 627 | &spec->multiout.max_channels); |
659 | if (err >= 0 && spec->need_dac_fix) | ||
660 | spec->multiout.num_dacs = spec->multiout.max_channels / 2; | ||
661 | return err; | 628 | return err; |
662 | } | 629 | } |
663 | 630 | ||
@@ -2496,10 +2463,6 @@ static void conexant_check_dig_outs(struct hda_codec *codec, | |||
2496 | continue; | 2463 | continue; |
2497 | if (snd_hda_get_connections(codec, *dig_pins, nid_loc, 1) != 1) | 2464 | if (snd_hda_get_connections(codec, *dig_pins, nid_loc, 1) != 1) |
2498 | continue; | 2465 | continue; |
2499 | if (spec->slave_dig_outs[0]) | ||
2500 | nid_loc++; | ||
2501 | else | ||
2502 | nid_loc = spec->slave_dig_outs; | ||
2503 | } | 2466 | } |
2504 | } | 2467 | } |
2505 | 2468 | ||
@@ -3141,626 +3104,12 @@ static int patch_cxt5066(struct hda_codec *codec) | |||
3141 | return 0; | 3104 | return 0; |
3142 | } | 3105 | } |
3143 | 3106 | ||
3144 | /* | 3107 | #endif /* ENABLE_CXT_STATIC_QUIRKS */ |
3145 | * Automatic parser for CX20641 & co | ||
3146 | */ | ||
3147 | 3108 | ||
3148 | static int cx_auto_capture_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
3149 | struct hda_codec *codec, | ||
3150 | unsigned int stream_tag, | ||
3151 | unsigned int format, | ||
3152 | struct snd_pcm_substream *substream) | ||
3153 | { | ||
3154 | struct conexant_spec *spec = codec->spec; | ||
3155 | hda_nid_t adc = spec->imux_info[spec->cur_mux[0]].adc; | ||
3156 | if (spec->adc_switching) { | ||
3157 | spec->cur_adc = adc; | ||
3158 | spec->cur_adc_stream_tag = stream_tag; | ||
3159 | spec->cur_adc_format = format; | ||
3160 | } | ||
3161 | snd_hda_codec_setup_stream(codec, adc, stream_tag, 0, format); | ||
3162 | return 0; | ||
3163 | } | ||
3164 | |||
3165 | static int cx_auto_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
3166 | struct hda_codec *codec, | ||
3167 | struct snd_pcm_substream *substream) | ||
3168 | { | ||
3169 | struct conexant_spec *spec = codec->spec; | ||
3170 | snd_hda_codec_cleanup_stream(codec, spec->cur_adc); | ||
3171 | spec->cur_adc = 0; | ||
3172 | return 0; | ||
3173 | } | ||
3174 | |||
3175 | static const struct hda_pcm_stream cx_auto_pcm_analog_capture = { | ||
3176 | .substreams = 1, | ||
3177 | .channels_min = 2, | ||
3178 | .channels_max = 2, | ||
3179 | .nid = 0, /* fill later */ | ||
3180 | .ops = { | ||
3181 | .prepare = cx_auto_capture_pcm_prepare, | ||
3182 | .cleanup = cx_auto_capture_pcm_cleanup | ||
3183 | }, | ||
3184 | }; | ||
3185 | |||
3186 | static const hda_nid_t cx_auto_adc_nids[] = { 0x14 }; | ||
3187 | |||
3188 | #define get_connection_index(codec, mux, nid)\ | ||
3189 | snd_hda_get_conn_index(codec, mux, nid, 0) | ||
3190 | |||
3191 | /* get an unassigned DAC from the given list. | ||
3192 | * Return the nid if found and reduce the DAC list, or return zero if | ||
3193 | * not found | ||
3194 | */ | ||
3195 | static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t pin, | ||
3196 | hda_nid_t *dacs, int *num_dacs) | ||
3197 | { | ||
3198 | int i, nums = *num_dacs; | ||
3199 | hda_nid_t ret = 0; | ||
3200 | |||
3201 | for (i = 0; i < nums; i++) { | ||
3202 | if (get_connection_index(codec, pin, dacs[i]) >= 0) { | ||
3203 | ret = dacs[i]; | ||
3204 | break; | ||
3205 | } | ||
3206 | } | ||
3207 | if (!ret) | ||
3208 | return 0; | ||
3209 | if (--nums > 0) | ||
3210 | memmove(dacs, dacs + 1, nums * sizeof(hda_nid_t)); | ||
3211 | *num_dacs = nums; | ||
3212 | return ret; | ||
3213 | } | ||
3214 | |||
3215 | #define MAX_AUTO_DACS 5 | ||
3216 | |||
3217 | #define DAC_SLAVE_FLAG 0x8000 /* filled dac is a slave */ | ||
3218 | |||
3219 | /* fill analog DAC list from the widget tree */ | ||
3220 | static int fill_cx_auto_dacs(struct hda_codec *codec, hda_nid_t *dacs) | ||
3221 | { | ||
3222 | hda_nid_t nid, end_nid; | ||
3223 | int nums = 0; | ||
3224 | |||
3225 | end_nid = codec->start_nid + codec->num_nodes; | ||
3226 | for (nid = codec->start_nid; nid < end_nid; nid++) { | ||
3227 | unsigned int wcaps = get_wcaps(codec, nid); | ||
3228 | unsigned int type = get_wcaps_type(wcaps); | ||
3229 | if (type == AC_WID_AUD_OUT && !(wcaps & AC_WCAP_DIGITAL)) { | ||
3230 | dacs[nums++] = nid; | ||
3231 | if (nums >= MAX_AUTO_DACS) | ||
3232 | break; | ||
3233 | } | ||
3234 | } | ||
3235 | return nums; | ||
3236 | } | ||
3237 | |||
3238 | /* fill pin_dac_pair list from the pin and dac list */ | ||
3239 | static int fill_dacs_for_pins(struct hda_codec *codec, hda_nid_t *pins, | ||
3240 | int num_pins, hda_nid_t *dacs, int *rest, | ||
3241 | struct pin_dac_pair *filled, int nums, | ||
3242 | int type) | ||
3243 | { | ||
3244 | int i, start = nums; | ||
3245 | |||
3246 | for (i = 0; i < num_pins; i++, nums++) { | ||
3247 | filled[nums].pin = pins[i]; | ||
3248 | filled[nums].type = type; | ||
3249 | filled[nums].dac = get_unassigned_dac(codec, pins[i], dacs, rest); | ||
3250 | if (filled[nums].dac) | ||
3251 | continue; | ||
3252 | if (filled[start].dac && get_connection_index(codec, pins[i], filled[start].dac) >= 0) { | ||
3253 | filled[nums].dac = filled[start].dac | DAC_SLAVE_FLAG; | ||
3254 | continue; | ||
3255 | } | ||
3256 | if (filled[0].dac && get_connection_index(codec, pins[i], filled[0].dac) >= 0) { | ||
3257 | filled[nums].dac = filled[0].dac | DAC_SLAVE_FLAG; | ||
3258 | continue; | ||
3259 | } | ||
3260 | snd_printdd("Failed to find a DAC for pin 0x%x", pins[i]); | ||
3261 | } | ||
3262 | return nums; | ||
3263 | } | ||
3264 | |||
3265 | /* parse analog output paths */ | ||
3266 | static void cx_auto_parse_output(struct hda_codec *codec) | ||
3267 | { | ||
3268 | struct conexant_spec *spec = codec->spec; | ||
3269 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
3270 | hda_nid_t dacs[MAX_AUTO_DACS]; | ||
3271 | int i, j, nums, rest; | ||
3272 | |||
3273 | rest = fill_cx_auto_dacs(codec, dacs); | ||
3274 | /* parse all analog output pins */ | ||
3275 | nums = fill_dacs_for_pins(codec, cfg->line_out_pins, cfg->line_outs, | ||
3276 | dacs, &rest, spec->dac_info, 0, | ||
3277 | AUTO_PIN_LINE_OUT); | ||
3278 | nums = fill_dacs_for_pins(codec, cfg->hp_pins, cfg->hp_outs, | ||
3279 | dacs, &rest, spec->dac_info, nums, | ||
3280 | AUTO_PIN_HP_OUT); | ||
3281 | nums = fill_dacs_for_pins(codec, cfg->speaker_pins, cfg->speaker_outs, | ||
3282 | dacs, &rest, spec->dac_info, nums, | ||
3283 | AUTO_PIN_SPEAKER_OUT); | ||
3284 | spec->dac_info_filled = nums; | ||
3285 | /* fill multiout struct */ | ||
3286 | for (i = 0; i < nums; i++) { | ||
3287 | hda_nid_t dac = spec->dac_info[i].dac; | ||
3288 | if (!dac || (dac & DAC_SLAVE_FLAG)) | ||
3289 | continue; | ||
3290 | switch (spec->dac_info[i].type) { | ||
3291 | case AUTO_PIN_LINE_OUT: | ||
3292 | spec->private_dac_nids[spec->multiout.num_dacs] = dac; | ||
3293 | spec->multiout.num_dacs++; | ||
3294 | break; | ||
3295 | case AUTO_PIN_HP_OUT: | ||
3296 | case AUTO_PIN_SPEAKER_OUT: | ||
3297 | if (!spec->multiout.hp_nid) { | ||
3298 | spec->multiout.hp_nid = dac; | ||
3299 | break; | ||
3300 | } | ||
3301 | for (j = 0; j < ARRAY_SIZE(spec->multiout.extra_out_nid); j++) | ||
3302 | if (!spec->multiout.extra_out_nid[j]) { | ||
3303 | spec->multiout.extra_out_nid[j] = dac; | ||
3304 | break; | ||
3305 | } | ||
3306 | break; | ||
3307 | } | ||
3308 | } | ||
3309 | spec->multiout.dac_nids = spec->private_dac_nids; | ||
3310 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | ||
3311 | |||
3312 | for (i = 0; i < cfg->hp_outs; i++) { | ||
3313 | if (is_jack_detectable(codec, cfg->hp_pins[i])) { | ||
3314 | spec->auto_mute = 1; | ||
3315 | break; | ||
3316 | } | ||
3317 | } | ||
3318 | if (spec->auto_mute && | ||
3319 | cfg->line_out_pins[0] && | ||
3320 | cfg->line_out_type != AUTO_PIN_SPEAKER_OUT && | ||
3321 | cfg->line_out_pins[0] != cfg->hp_pins[0] && | ||
3322 | cfg->line_out_pins[0] != cfg->speaker_pins[0]) { | ||
3323 | for (i = 0; i < cfg->line_outs; i++) { | ||
3324 | if (is_jack_detectable(codec, cfg->line_out_pins[i])) { | ||
3325 | spec->detect_line = 1; | ||
3326 | break; | ||
3327 | } | ||
3328 | } | ||
3329 | spec->automute_lines = spec->detect_line; | ||
3330 | } | ||
3331 | |||
3332 | spec->vmaster_nid = spec->private_dac_nids[0]; | ||
3333 | } | ||
3334 | |||
3335 | static void cx_auto_turn_eapd(struct hda_codec *codec, int num_pins, | ||
3336 | hda_nid_t *pins, bool on); | ||
3337 | |||
3338 | static void do_automute(struct hda_codec *codec, int num_pins, | ||
3339 | hda_nid_t *pins, bool on) | ||
3340 | { | ||
3341 | struct conexant_spec *spec = codec->spec; | ||
3342 | int i; | ||
3343 | for (i = 0; i < num_pins; i++) | ||
3344 | snd_hda_set_pin_ctl(codec, pins[i], on ? PIN_OUT : 0); | ||
3345 | if (spec->pin_eapd_ctrls) | ||
3346 | cx_auto_turn_eapd(codec, num_pins, pins, on); | ||
3347 | } | ||
3348 | |||
3349 | static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins) | ||
3350 | { | ||
3351 | int i, present = 0; | ||
3352 | |||
3353 | for (i = 0; i < num_pins; i++) { | ||
3354 | hda_nid_t nid = pins[i]; | ||
3355 | if (!nid || !is_jack_detectable(codec, nid)) | ||
3356 | break; | ||
3357 | present |= snd_hda_jack_detect(codec, nid); | ||
3358 | } | ||
3359 | return present; | ||
3360 | } | ||
3361 | |||
3362 | /* auto-mute/unmute speaker and line outs according to headphone jack */ | ||
3363 | static void cx_auto_update_speakers(struct hda_codec *codec) | ||
3364 | { | ||
3365 | struct conexant_spec *spec = codec->spec; | ||
3366 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
3367 | int on = 1; | ||
3368 | |||
3369 | /* turn on HP EAPD when HP jacks are present */ | ||
3370 | if (spec->pin_eapd_ctrls) { | ||
3371 | if (spec->auto_mute) | ||
3372 | on = spec->hp_present; | ||
3373 | cx_auto_turn_eapd(codec, cfg->hp_outs, cfg->hp_pins, on); | ||
3374 | } | ||
3375 | |||
3376 | /* mute speakers in auto-mode if HP or LO jacks are plugged */ | ||
3377 | if (spec->auto_mute) | ||
3378 | on = !(spec->hp_present || | ||
3379 | (spec->detect_line && spec->line_present)); | ||
3380 | do_automute(codec, cfg->speaker_outs, cfg->speaker_pins, on); | ||
3381 | |||
3382 | /* toggle line-out mutes if needed, too */ | ||
3383 | /* if LO is a copy of either HP or Speaker, don't need to handle it */ | ||
3384 | if (cfg->line_out_pins[0] == cfg->hp_pins[0] || | ||
3385 | cfg->line_out_pins[0] == cfg->speaker_pins[0]) | ||
3386 | return; | ||
3387 | if (spec->auto_mute) { | ||
3388 | /* mute LO in auto-mode when HP jack is present */ | ||
3389 | if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT || | ||
3390 | spec->automute_lines) | ||
3391 | on = !spec->hp_present; | ||
3392 | else | ||
3393 | on = 1; | ||
3394 | } | ||
3395 | do_automute(codec, cfg->line_outs, cfg->line_out_pins, on); | ||
3396 | } | ||
3397 | |||
3398 | static void cx_auto_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack) | ||
3399 | { | ||
3400 | struct conexant_spec *spec = codec->spec; | ||
3401 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
3402 | |||
3403 | if (!spec->auto_mute) | ||
3404 | return; | ||
3405 | spec->hp_present = detect_jacks(codec, cfg->hp_outs, cfg->hp_pins); | ||
3406 | cx_auto_update_speakers(codec); | ||
3407 | } | ||
3408 | |||
3409 | static void cx_auto_line_automute(struct hda_codec *codec, struct hda_jack_tbl *jack) | ||
3410 | { | ||
3411 | struct conexant_spec *spec = codec->spec; | ||
3412 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
3413 | |||
3414 | if (!spec->auto_mute || !spec->detect_line) | ||
3415 | return; | ||
3416 | spec->line_present = detect_jacks(codec, cfg->line_outs, | ||
3417 | cfg->line_out_pins); | ||
3418 | cx_auto_update_speakers(codec); | ||
3419 | } | ||
3420 | |||
3421 | static int cx_automute_mode_info(struct snd_kcontrol *kcontrol, | ||
3422 | struct snd_ctl_elem_info *uinfo) | ||
3423 | { | ||
3424 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
3425 | struct conexant_spec *spec = codec->spec; | ||
3426 | static const char * const texts3[] = { | ||
3427 | "Disabled", "Speaker Only", "Line Out+Speaker" | ||
3428 | }; | ||
3429 | |||
3430 | if (spec->automute_hp_lo) | ||
3431 | return snd_hda_enum_helper_info(kcontrol, uinfo, 3, texts3); | ||
3432 | return snd_hda_enum_bool_helper_info(kcontrol, uinfo); | ||
3433 | } | ||
3434 | |||
3435 | static int cx_automute_mode_get(struct snd_kcontrol *kcontrol, | ||
3436 | struct snd_ctl_elem_value *ucontrol) | ||
3437 | { | ||
3438 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
3439 | struct conexant_spec *spec = codec->spec; | ||
3440 | unsigned int val; | ||
3441 | if (!spec->auto_mute) | ||
3442 | val = 0; | ||
3443 | else if (!spec->automute_lines) | ||
3444 | val = 1; | ||
3445 | else | ||
3446 | val = 2; | ||
3447 | ucontrol->value.enumerated.item[0] = val; | ||
3448 | return 0; | ||
3449 | } | ||
3450 | |||
3451 | static int cx_automute_mode_put(struct snd_kcontrol *kcontrol, | ||
3452 | struct snd_ctl_elem_value *ucontrol) | ||
3453 | { | ||
3454 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
3455 | struct conexant_spec *spec = codec->spec; | ||
3456 | |||
3457 | switch (ucontrol->value.enumerated.item[0]) { | ||
3458 | case 0: | ||
3459 | if (!spec->auto_mute) | ||
3460 | return 0; | ||
3461 | spec->auto_mute = 0; | ||
3462 | break; | ||
3463 | case 1: | ||
3464 | if (spec->auto_mute && !spec->automute_lines) | ||
3465 | return 0; | ||
3466 | spec->auto_mute = 1; | ||
3467 | spec->automute_lines = 0; | ||
3468 | break; | ||
3469 | case 2: | ||
3470 | if (!spec->automute_hp_lo) | ||
3471 | return -EINVAL; | ||
3472 | if (spec->auto_mute && spec->automute_lines) | ||
3473 | return 0; | ||
3474 | spec->auto_mute = 1; | ||
3475 | spec->automute_lines = 1; | ||
3476 | break; | ||
3477 | default: | ||
3478 | return -EINVAL; | ||
3479 | } | ||
3480 | cx_auto_update_speakers(codec); | ||
3481 | return 1; | ||
3482 | } | ||
3483 | |||
3484 | static const struct snd_kcontrol_new cx_automute_mode_enum[] = { | ||
3485 | { | ||
3486 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
3487 | .name = "Auto-Mute Mode", | ||
3488 | .info = cx_automute_mode_info, | ||
3489 | .get = cx_automute_mode_get, | ||
3490 | .put = cx_automute_mode_put, | ||
3491 | }, | ||
3492 | { } | ||
3493 | }; | ||
3494 | |||
3495 | static int cx_auto_mux_enum_info(struct snd_kcontrol *kcontrol, | ||
3496 | struct snd_ctl_elem_info *uinfo) | ||
3497 | { | ||
3498 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
3499 | struct conexant_spec *spec = codec->spec; | ||
3500 | |||
3501 | return snd_hda_input_mux_info(&spec->private_imux, uinfo); | ||
3502 | } | ||
3503 | |||
3504 | static int cx_auto_mux_enum_get(struct snd_kcontrol *kcontrol, | ||
3505 | struct snd_ctl_elem_value *ucontrol) | ||
3506 | { | ||
3507 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
3508 | struct conexant_spec *spec = codec->spec; | ||
3509 | |||
3510 | ucontrol->value.enumerated.item[0] = spec->cur_mux[0]; | ||
3511 | return 0; | ||
3512 | } | ||
3513 | |||
3514 | /* look for the route the given pin from mux and return the index; | ||
3515 | * if do_select is set, actually select the route. | ||
3516 | */ | ||
3517 | static int __select_input_connection(struct hda_codec *codec, hda_nid_t mux, | ||
3518 | hda_nid_t pin, hda_nid_t *srcp, | ||
3519 | bool do_select, int depth) | ||
3520 | { | ||
3521 | struct conexant_spec *spec = codec->spec; | ||
3522 | hda_nid_t conn[HDA_MAX_NUM_INPUTS]; | ||
3523 | int startidx, i, nums; | ||
3524 | |||
3525 | switch (get_wcaps_type(get_wcaps(codec, mux))) { | ||
3526 | case AC_WID_AUD_IN: | ||
3527 | case AC_WID_AUD_SEL: | ||
3528 | case AC_WID_AUD_MIX: | ||
3529 | break; | ||
3530 | default: | ||
3531 | return -1; | ||
3532 | } | ||
3533 | |||
3534 | nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn)); | ||
3535 | for (i = 0; i < nums; i++) | ||
3536 | if (conn[i] == pin) { | ||
3537 | if (do_select) | ||
3538 | snd_hda_codec_write(codec, mux, 0, | ||
3539 | AC_VERB_SET_CONNECT_SEL, i); | ||
3540 | if (srcp) | ||
3541 | *srcp = mux; | ||
3542 | return i; | ||
3543 | } | ||
3544 | depth++; | ||
3545 | if (depth == 2) | ||
3546 | return -1; | ||
3547 | |||
3548 | /* Try to rotate around connections to avoid one boost controlling | ||
3549 | another input path as well */ | ||
3550 | startidx = 0; | ||
3551 | for (i = 0; i < spec->private_imux.num_items; i++) | ||
3552 | if (spec->imux_info[i].pin == pin) { | ||
3553 | startidx = i; | ||
3554 | break; | ||
3555 | } | ||
3556 | |||
3557 | for (i = 0; i < nums; i++) { | ||
3558 | int j = (i + startidx) % nums; | ||
3559 | int ret = __select_input_connection(codec, conn[j], pin, srcp, | ||
3560 | do_select, depth); | ||
3561 | if (ret >= 0) { | ||
3562 | if (do_select) | ||
3563 | snd_hda_codec_write(codec, mux, 0, | ||
3564 | AC_VERB_SET_CONNECT_SEL, j); | ||
3565 | return j; | ||
3566 | } | ||
3567 | } | ||
3568 | return -1; | ||
3569 | } | ||
3570 | |||
3571 | static void select_input_connection(struct hda_codec *codec, hda_nid_t mux, | ||
3572 | hda_nid_t pin) | ||
3573 | { | ||
3574 | __select_input_connection(codec, mux, pin, NULL, true, 0); | ||
3575 | } | ||
3576 | |||
3577 | static int get_input_connection(struct hda_codec *codec, hda_nid_t mux, | ||
3578 | hda_nid_t pin) | ||
3579 | { | ||
3580 | return __select_input_connection(codec, mux, pin, NULL, false, 0); | ||
3581 | } | ||
3582 | |||
3583 | static int cx_auto_mux_enum_update(struct hda_codec *codec, | ||
3584 | const struct hda_input_mux *imux, | ||
3585 | unsigned int idx) | ||
3586 | { | ||
3587 | struct conexant_spec *spec = codec->spec; | ||
3588 | hda_nid_t adc; | ||
3589 | int changed = 1; | ||
3590 | |||
3591 | if (!imux->num_items) | ||
3592 | return 0; | ||
3593 | if (idx >= imux->num_items) | ||
3594 | idx = imux->num_items - 1; | ||
3595 | if (spec->cur_mux[0] == idx) | ||
3596 | changed = 0; | ||
3597 | adc = spec->imux_info[idx].adc; | ||
3598 | select_input_connection(codec, spec->imux_info[idx].adc, | ||
3599 | spec->imux_info[idx].pin); | ||
3600 | if (spec->cur_adc && spec->cur_adc != adc) { | ||
3601 | /* stream is running, let's swap the current ADC */ | ||
3602 | __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1); | ||
3603 | spec->cur_adc = adc; | ||
3604 | snd_hda_codec_setup_stream(codec, adc, | ||
3605 | spec->cur_adc_stream_tag, 0, | ||
3606 | spec->cur_adc_format); | ||
3607 | } | ||
3608 | spec->cur_mux[0] = idx; | ||
3609 | return changed; | ||
3610 | } | ||
3611 | 3109 | ||
3612 | static int cx_auto_mux_enum_put(struct snd_kcontrol *kcontrol, | 3110 | /* |
3613 | struct snd_ctl_elem_value *ucontrol) | 3111 | * Automatic parser for CX20641 & co |
3614 | { | ||
3615 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
3616 | struct conexant_spec *spec = codec->spec; | ||
3617 | |||
3618 | return cx_auto_mux_enum_update(codec, &spec->private_imux, | ||
3619 | ucontrol->value.enumerated.item[0]); | ||
3620 | } | ||
3621 | |||
3622 | static const struct snd_kcontrol_new cx_auto_capture_mixers[] = { | ||
3623 | { | ||
3624 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
3625 | .name = "Capture Source", | ||
3626 | .info = cx_auto_mux_enum_info, | ||
3627 | .get = cx_auto_mux_enum_get, | ||
3628 | .put = cx_auto_mux_enum_put | ||
3629 | }, | ||
3630 | {} | ||
3631 | }; | ||
3632 | |||
3633 | static bool select_automic(struct hda_codec *codec, int idx, bool detect) | ||
3634 | { | ||
3635 | struct conexant_spec *spec = codec->spec; | ||
3636 | if (idx < 0) | ||
3637 | return false; | ||
3638 | if (detect && !snd_hda_jack_detect(codec, spec->imux_info[idx].pin)) | ||
3639 | return false; | ||
3640 | cx_auto_mux_enum_update(codec, &spec->private_imux, idx); | ||
3641 | return true; | ||
3642 | } | ||
3643 | |||
3644 | /* automatic switch internal and external mic */ | ||
3645 | static void cx_auto_automic(struct hda_codec *codec, struct hda_jack_tbl *jack) | ||
3646 | { | ||
3647 | struct conexant_spec *spec = codec->spec; | ||
3648 | |||
3649 | if (!spec->auto_mic) | ||
3650 | return; | ||
3651 | if (!select_automic(codec, spec->auto_mic_ext, true)) | ||
3652 | if (!select_automic(codec, spec->auto_mic_dock, true)) | ||
3653 | select_automic(codec, spec->auto_mic_int, false); | ||
3654 | } | ||
3655 | |||
3656 | /* check whether the pin config is suitable for auto-mic switching; | ||
3657 | * auto-mic is enabled only when one int-mic and one ext- and/or | ||
3658 | * one dock-mic exist | ||
3659 | */ | 3112 | */ |
3660 | static void cx_auto_check_auto_mic(struct hda_codec *codec) | ||
3661 | { | ||
3662 | struct conexant_spec *spec = codec->spec; | ||
3663 | int pset[INPUT_PIN_ATTR_NORMAL + 1]; | ||
3664 | int i; | ||
3665 | |||
3666 | for (i = 0; i < ARRAY_SIZE(pset); i++) | ||
3667 | pset[i] = -1; | ||
3668 | for (i = 0; i < spec->private_imux.num_items; i++) { | ||
3669 | hda_nid_t pin = spec->imux_info[i].pin; | ||
3670 | unsigned int def_conf = snd_hda_codec_get_pincfg(codec, pin); | ||
3671 | int type, attr; | ||
3672 | attr = snd_hda_get_input_pin_attr(def_conf); | ||
3673 | if (attr == INPUT_PIN_ATTR_UNUSED) | ||
3674 | return; /* invalid entry */ | ||
3675 | if (attr > INPUT_PIN_ATTR_NORMAL) | ||
3676 | attr = INPUT_PIN_ATTR_NORMAL; | ||
3677 | if (attr != INPUT_PIN_ATTR_INT && | ||
3678 | !is_jack_detectable(codec, pin)) | ||
3679 | return; /* non-detectable pin */ | ||
3680 | type = get_defcfg_device(def_conf); | ||
3681 | if (type != AC_JACK_MIC_IN && | ||
3682 | (attr != INPUT_PIN_ATTR_DOCK || type != AC_JACK_LINE_IN)) | ||
3683 | return; /* no valid input type */ | ||
3684 | if (pset[attr] >= 0) | ||
3685 | return; /* already occupied */ | ||
3686 | pset[attr] = i; | ||
3687 | } | ||
3688 | if (pset[INPUT_PIN_ATTR_INT] < 0 || | ||
3689 | (pset[INPUT_PIN_ATTR_NORMAL] < 0 && pset[INPUT_PIN_ATTR_DOCK])) | ||
3690 | return; /* no input to switch*/ | ||
3691 | spec->auto_mic = 1; | ||
3692 | spec->auto_mic_ext = pset[INPUT_PIN_ATTR_NORMAL]; | ||
3693 | spec->auto_mic_dock = pset[INPUT_PIN_ATTR_DOCK]; | ||
3694 | spec->auto_mic_int = pset[INPUT_PIN_ATTR_INT]; | ||
3695 | } | ||
3696 | |||
3697 | static void cx_auto_parse_input(struct hda_codec *codec) | ||
3698 | { | ||
3699 | struct conexant_spec *spec = codec->spec; | ||
3700 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
3701 | struct hda_input_mux *imux; | ||
3702 | int i, j; | ||
3703 | |||
3704 | imux = &spec->private_imux; | ||
3705 | for (i = 0; i < cfg->num_inputs; i++) { | ||
3706 | for (j = 0; j < spec->num_adc_nids; j++) { | ||
3707 | hda_nid_t adc = spec->adc_nids[j]; | ||
3708 | int idx = get_input_connection(codec, adc, | ||
3709 | cfg->inputs[i].pin); | ||
3710 | if (idx >= 0) { | ||
3711 | const char *label; | ||
3712 | label = hda_get_autocfg_input_label(codec, cfg, i); | ||
3713 | spec->imux_info[imux->num_items].index = i; | ||
3714 | spec->imux_info[imux->num_items].boost = 0; | ||
3715 | spec->imux_info[imux->num_items].adc = adc; | ||
3716 | spec->imux_info[imux->num_items].pin = | ||
3717 | cfg->inputs[i].pin; | ||
3718 | snd_hda_add_imux_item(imux, label, idx, NULL); | ||
3719 | break; | ||
3720 | } | ||
3721 | } | ||
3722 | } | ||
3723 | if (imux->num_items >= 2 && cfg->num_inputs == imux->num_items) | ||
3724 | cx_auto_check_auto_mic(codec); | ||
3725 | if (imux->num_items > 1) { | ||
3726 | for (i = 1; i < imux->num_items; i++) { | ||
3727 | if (spec->imux_info[i].adc != spec->imux_info[0].adc) { | ||
3728 | spec->adc_switching = 1; | ||
3729 | break; | ||
3730 | } | ||
3731 | } | ||
3732 | } | ||
3733 | } | ||
3734 | |||
3735 | /* get digital-input audio widget corresponding to the given pin */ | ||
3736 | static hda_nid_t cx_auto_get_dig_in(struct hda_codec *codec, hda_nid_t pin) | ||
3737 | { | ||
3738 | hda_nid_t nid, end_nid; | ||
3739 | |||
3740 | end_nid = codec->start_nid + codec->num_nodes; | ||
3741 | for (nid = codec->start_nid; nid < end_nid; nid++) { | ||
3742 | unsigned int wcaps = get_wcaps(codec, nid); | ||
3743 | unsigned int type = get_wcaps_type(wcaps); | ||
3744 | if (type == AC_WID_AUD_IN && (wcaps & AC_WCAP_DIGITAL)) { | ||
3745 | if (get_connection_index(codec, nid, pin) >= 0) | ||
3746 | return nid; | ||
3747 | } | ||
3748 | } | ||
3749 | return 0; | ||
3750 | } | ||
3751 | |||
3752 | static void cx_auto_parse_digital(struct hda_codec *codec) | ||
3753 | { | ||
3754 | struct conexant_spec *spec = codec->spec; | ||
3755 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
3756 | hda_nid_t nid; | ||
3757 | |||
3758 | if (cfg->dig_outs && | ||
3759 | snd_hda_get_connections(codec, cfg->dig_out_pins[0], &nid, 1) == 1) | ||
3760 | spec->multiout.dig_out_nid = nid; | ||
3761 | if (cfg->dig_in_pin) | ||
3762 | spec->dig_in_nid = cx_auto_get_dig_in(codec, cfg->dig_in_pin); | ||
3763 | } | ||
3764 | 3113 | ||
3765 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | 3114 | #ifdef CONFIG_SND_HDA_INPUT_BEEP |
3766 | static void cx_auto_parse_beep(struct hda_codec *codec) | 3115 | static void cx_auto_parse_beep(struct hda_codec *codec) |
@@ -3802,24 +3151,8 @@ static void cx_auto_parse_eapd(struct hda_codec *codec) | |||
3802 | * OTOH, if only one or two EAPDs are found, it's an old chip, | 3151 | * OTOH, if only one or two EAPDs are found, it's an old chip, |
3803 | * thus it might control over all pins. | 3152 | * thus it might control over all pins. |
3804 | */ | 3153 | */ |
3805 | spec->pin_eapd_ctrls = spec->num_eapds > 2; | 3154 | if (spec->num_eapds > 2) |
3806 | } | 3155 | spec->gen.own_eapd_ctl = 1; |
3807 | |||
3808 | static int cx_auto_parse_auto_config(struct hda_codec *codec) | ||
3809 | { | ||
3810 | struct conexant_spec *spec = codec->spec; | ||
3811 | int err; | ||
3812 | |||
3813 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL); | ||
3814 | if (err < 0) | ||
3815 | return err; | ||
3816 | |||
3817 | cx_auto_parse_output(codec); | ||
3818 | cx_auto_parse_input(codec); | ||
3819 | cx_auto_parse_digital(codec); | ||
3820 | cx_auto_parse_beep(codec); | ||
3821 | cx_auto_parse_eapd(codec); | ||
3822 | return 0; | ||
3823 | } | 3156 | } |
3824 | 3157 | ||
3825 | static void cx_auto_turn_eapd(struct hda_codec *codec, int num_pins, | 3158 | static void cx_auto_turn_eapd(struct hda_codec *codec, int num_pins, |
@@ -3834,565 +3167,39 @@ static void cx_auto_turn_eapd(struct hda_codec *codec, int num_pins, | |||
3834 | } | 3167 | } |
3835 | } | 3168 | } |
3836 | 3169 | ||
3837 | static void select_connection(struct hda_codec *codec, hda_nid_t pin, | ||
3838 | hda_nid_t src) | ||
3839 | { | ||
3840 | int idx = get_connection_index(codec, pin, src); | ||
3841 | if (idx >= 0) | ||
3842 | snd_hda_codec_write(codec, pin, 0, | ||
3843 | AC_VERB_SET_CONNECT_SEL, idx); | ||
3844 | } | ||
3845 | |||
3846 | static void mute_outputs(struct hda_codec *codec, int num_nids, | ||
3847 | const hda_nid_t *nids) | ||
3848 | { | ||
3849 | int i, val; | ||
3850 | |||
3851 | for (i = 0; i < num_nids; i++) { | ||
3852 | hda_nid_t nid = nids[i]; | ||
3853 | if (!(get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) | ||
3854 | continue; | ||
3855 | if (query_amp_caps(codec, nid, HDA_OUTPUT) & AC_AMPCAP_MUTE) | ||
3856 | val = AMP_OUT_MUTE; | ||
3857 | else | ||
3858 | val = AMP_OUT_ZERO; | ||
3859 | snd_hda_codec_write(codec, nid, 0, | ||
3860 | AC_VERB_SET_AMP_GAIN_MUTE, val); | ||
3861 | } | ||
3862 | } | ||
3863 | |||
3864 | static void enable_unsol_pins(struct hda_codec *codec, int num_pins, | ||
3865 | hda_nid_t *pins, unsigned int action, | ||
3866 | hda_jack_callback cb) | ||
3867 | { | ||
3868 | int i; | ||
3869 | for (i = 0; i < num_pins; i++) | ||
3870 | snd_hda_jack_detect_enable_callback(codec, pins[i], action, cb); | ||
3871 | } | ||
3872 | |||
3873 | static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) | ||
3874 | { | ||
3875 | int i; | ||
3876 | for (i = 0; i < nums; i++) | ||
3877 | if (list[i] == nid) | ||
3878 | return true; | ||
3879 | return false; | ||
3880 | } | ||
3881 | |||
3882 | /* is the given NID found in any of autocfg items? */ | ||
3883 | static bool found_in_autocfg(struct auto_pin_cfg *cfg, hda_nid_t nid) | ||
3884 | { | ||
3885 | int i; | ||
3886 | |||
3887 | if (found_in_nid_list(nid, cfg->line_out_pins, cfg->line_outs) || | ||
3888 | found_in_nid_list(nid, cfg->hp_pins, cfg->hp_outs) || | ||
3889 | found_in_nid_list(nid, cfg->speaker_pins, cfg->speaker_outs) || | ||
3890 | found_in_nid_list(nid, cfg->dig_out_pins, cfg->dig_outs)) | ||
3891 | return true; | ||
3892 | for (i = 0; i < cfg->num_inputs; i++) | ||
3893 | if (cfg->inputs[i].pin == nid) | ||
3894 | return true; | ||
3895 | if (cfg->dig_in_pin == nid) | ||
3896 | return true; | ||
3897 | return false; | ||
3898 | } | ||
3899 | |||
3900 | /* clear unsol-event tags on unused pins; Conexant codecs seem to leave | ||
3901 | * invalid unsol tags by some reason | ||
3902 | */ | ||
3903 | static void clear_unsol_on_unused_pins(struct hda_codec *codec) | ||
3904 | { | ||
3905 | struct conexant_spec *spec = codec->spec; | ||
3906 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
3907 | int i; | ||
3908 | |||
3909 | for (i = 0; i < codec->init_pins.used; i++) { | ||
3910 | struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i); | ||
3911 | if (!found_in_autocfg(cfg, pin->nid)) | ||
3912 | snd_hda_codec_write(codec, pin->nid, 0, | ||
3913 | AC_VERB_SET_UNSOLICITED_ENABLE, 0); | ||
3914 | } | ||
3915 | } | ||
3916 | |||
3917 | /* turn on/off EAPD according to Master switch */ | 3170 | /* turn on/off EAPD according to Master switch */ |
3918 | static void cx_auto_vmaster_hook(void *private_data, int enabled) | 3171 | static void cx_auto_vmaster_hook(void *private_data, int enabled) |
3919 | { | 3172 | { |
3920 | struct hda_codec *codec = private_data; | 3173 | struct hda_codec *codec = private_data; |
3921 | struct conexant_spec *spec = codec->spec; | 3174 | struct conexant_spec *spec = codec->spec; |
3922 | 3175 | ||
3923 | if (enabled && spec->pin_eapd_ctrls) { | ||
3924 | cx_auto_update_speakers(codec); | ||
3925 | return; | ||
3926 | } | ||
3927 | cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, enabled); | 3176 | cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, enabled); |
3928 | } | 3177 | } |
3929 | 3178 | ||
3930 | static void cx_auto_init_output(struct hda_codec *codec) | ||
3931 | { | ||
3932 | struct conexant_spec *spec = codec->spec; | ||
3933 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
3934 | hda_nid_t nid; | ||
3935 | int i; | ||
3936 | |||
3937 | mute_outputs(codec, spec->multiout.num_dacs, spec->multiout.dac_nids); | ||
3938 | for (i = 0; i < cfg->hp_outs; i++) { | ||
3939 | unsigned int val = PIN_OUT; | ||
3940 | if (snd_hda_query_pin_caps(codec, cfg->hp_pins[i]) & | ||
3941 | AC_PINCAP_HP_DRV) | ||
3942 | val |= AC_PINCTL_HP_EN; | ||
3943 | snd_hda_set_pin_ctl(codec, cfg->hp_pins[i], val); | ||
3944 | } | ||
3945 | mute_outputs(codec, cfg->hp_outs, cfg->hp_pins); | ||
3946 | mute_outputs(codec, cfg->line_outs, cfg->line_out_pins); | ||
3947 | mute_outputs(codec, cfg->speaker_outs, cfg->speaker_pins); | ||
3948 | for (i = 0; i < spec->dac_info_filled; i++) { | ||
3949 | nid = spec->dac_info[i].dac; | ||
3950 | if (!nid) | ||
3951 | nid = spec->multiout.dac_nids[0]; | ||
3952 | else if (nid & DAC_SLAVE_FLAG) | ||
3953 | nid &= ~DAC_SLAVE_FLAG; | ||
3954 | select_connection(codec, spec->dac_info[i].pin, nid); | ||
3955 | } | ||
3956 | if (spec->auto_mute) { | ||
3957 | enable_unsol_pins(codec, cfg->hp_outs, cfg->hp_pins, | ||
3958 | CONEXANT_HP_EVENT, cx_auto_hp_automute); | ||
3959 | spec->hp_present = detect_jacks(codec, cfg->hp_outs, | ||
3960 | cfg->hp_pins); | ||
3961 | if (spec->detect_line) { | ||
3962 | enable_unsol_pins(codec, cfg->line_outs, | ||
3963 | cfg->line_out_pins, | ||
3964 | CONEXANT_LINE_EVENT, | ||
3965 | cx_auto_line_automute); | ||
3966 | spec->line_present = | ||
3967 | detect_jacks(codec, cfg->line_outs, | ||
3968 | cfg->line_out_pins); | ||
3969 | } | ||
3970 | } | ||
3971 | cx_auto_update_speakers(codec); | ||
3972 | /* turn on all EAPDs if no individual EAPD control is available */ | ||
3973 | if (!spec->pin_eapd_ctrls) | ||
3974 | cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true); | ||
3975 | clear_unsol_on_unused_pins(codec); | ||
3976 | } | ||
3977 | |||
3978 | static void cx_auto_init_input(struct hda_codec *codec) | ||
3979 | { | ||
3980 | struct conexant_spec *spec = codec->spec; | ||
3981 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
3982 | int i, val; | ||
3983 | |||
3984 | for (i = 0; i < spec->num_adc_nids; i++) { | ||
3985 | hda_nid_t nid = spec->adc_nids[i]; | ||
3986 | if (!(get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) | ||
3987 | continue; | ||
3988 | if (query_amp_caps(codec, nid, HDA_INPUT) & AC_AMPCAP_MUTE) | ||
3989 | val = AMP_IN_MUTE(0); | ||
3990 | else | ||
3991 | val = AMP_IN_UNMUTE(0); | ||
3992 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
3993 | val); | ||
3994 | } | ||
3995 | |||
3996 | for (i = 0; i < cfg->num_inputs; i++) { | ||
3997 | hda_nid_t pin = cfg->inputs[i].pin; | ||
3998 | unsigned int type = PIN_IN; | ||
3999 | if (cfg->inputs[i].type == AUTO_PIN_MIC) | ||
4000 | type |= snd_hda_get_default_vref(codec, pin); | ||
4001 | snd_hda_set_pin_ctl(codec, pin, type); | ||
4002 | } | ||
4003 | |||
4004 | if (spec->auto_mic) { | ||
4005 | if (spec->auto_mic_ext >= 0) { | ||
4006 | snd_hda_jack_detect_enable_callback(codec, | ||
4007 | cfg->inputs[spec->auto_mic_ext].pin, | ||
4008 | CONEXANT_MIC_EVENT, cx_auto_automic); | ||
4009 | } | ||
4010 | if (spec->auto_mic_dock >= 0) { | ||
4011 | snd_hda_jack_detect_enable_callback(codec, | ||
4012 | cfg->inputs[spec->auto_mic_dock].pin, | ||
4013 | CONEXANT_MIC_EVENT, cx_auto_automic); | ||
4014 | } | ||
4015 | cx_auto_automic(codec, NULL); | ||
4016 | } else { | ||
4017 | select_input_connection(codec, spec->imux_info[0].adc, | ||
4018 | spec->imux_info[0].pin); | ||
4019 | } | ||
4020 | } | ||
4021 | |||
4022 | static void cx_auto_init_digital(struct hda_codec *codec) | ||
4023 | { | ||
4024 | struct conexant_spec *spec = codec->spec; | ||
4025 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
4026 | |||
4027 | if (spec->multiout.dig_out_nid) | ||
4028 | snd_hda_set_pin_ctl(codec, cfg->dig_out_pins[0], PIN_OUT); | ||
4029 | if (spec->dig_in_nid) | ||
4030 | snd_hda_set_pin_ctl(codec, cfg->dig_in_pin, PIN_IN); | ||
4031 | } | ||
4032 | |||
4033 | static int cx_auto_init(struct hda_codec *codec) | ||
4034 | { | ||
4035 | struct conexant_spec *spec = codec->spec; | ||
4036 | snd_hda_gen_apply_verbs(codec); | ||
4037 | cx_auto_init_output(codec); | ||
4038 | cx_auto_init_input(codec); | ||
4039 | cx_auto_init_digital(codec); | ||
4040 | snd_hda_sync_vmaster_hook(&spec->vmaster_mute); | ||
4041 | return 0; | ||
4042 | } | ||
4043 | |||
4044 | static int cx_auto_add_volume_idx(struct hda_codec *codec, const char *basename, | ||
4045 | const char *dir, int cidx, | ||
4046 | hda_nid_t nid, int hda_dir, int amp_idx, int chs) | ||
4047 | { | ||
4048 | static char name[44]; | ||
4049 | static struct snd_kcontrol_new knew[] = { | ||
4050 | HDA_CODEC_VOLUME(name, 0, 0, 0), | ||
4051 | HDA_CODEC_MUTE(name, 0, 0, 0), | ||
4052 | }; | ||
4053 | static const char * const sfx[2] = { "Volume", "Switch" }; | ||
4054 | int i, err; | ||
4055 | |||
4056 | for (i = 0; i < 2; i++) { | ||
4057 | struct snd_kcontrol *kctl; | ||
4058 | knew[i].private_value = HDA_COMPOSE_AMP_VAL(nid, chs, amp_idx, | ||
4059 | hda_dir); | ||
4060 | knew[i].subdevice = HDA_SUBDEV_AMP_FLAG; | ||
4061 | knew[i].index = cidx; | ||
4062 | snprintf(name, sizeof(name), "%s%s %s", basename, dir, sfx[i]); | ||
4063 | kctl = snd_ctl_new1(&knew[i], codec); | ||
4064 | if (!kctl) | ||
4065 | return -ENOMEM; | ||
4066 | err = snd_hda_ctl_add(codec, nid, kctl); | ||
4067 | if (err < 0) | ||
4068 | return err; | ||
4069 | if (!(query_amp_caps(codec, nid, hda_dir) & | ||
4070 | (AC_AMPCAP_MUTE | AC_AMPCAP_MIN_MUTE))) | ||
4071 | break; | ||
4072 | } | ||
4073 | return 0; | ||
4074 | } | ||
4075 | |||
4076 | #define cx_auto_add_volume(codec, str, dir, cidx, nid, hda_dir) \ | ||
4077 | cx_auto_add_volume_idx(codec, str, dir, cidx, nid, hda_dir, 0, 3) | ||
4078 | |||
4079 | #define cx_auto_add_pb_volume(codec, nid, str, idx) \ | ||
4080 | cx_auto_add_volume(codec, str, " Playback", idx, nid, HDA_OUTPUT) | ||
4081 | |||
4082 | static int try_add_pb_volume(struct hda_codec *codec, hda_nid_t dac, | ||
4083 | hda_nid_t pin, const char *name, int idx) | ||
4084 | { | ||
4085 | unsigned int caps; | ||
4086 | if (dac && !(dac & DAC_SLAVE_FLAG)) { | ||
4087 | caps = query_amp_caps(codec, dac, HDA_OUTPUT); | ||
4088 | if (caps & AC_AMPCAP_NUM_STEPS) | ||
4089 | return cx_auto_add_pb_volume(codec, dac, name, idx); | ||
4090 | } | ||
4091 | caps = query_amp_caps(codec, pin, HDA_OUTPUT); | ||
4092 | if (caps & AC_AMPCAP_NUM_STEPS) | ||
4093 | return cx_auto_add_pb_volume(codec, pin, name, idx); | ||
4094 | return 0; | ||
4095 | } | ||
4096 | |||
4097 | static bool is_2_1_speaker(struct conexant_spec *spec) | ||
4098 | { | ||
4099 | int i, type, num_spk = 0; | ||
4100 | |||
4101 | for (i = 0; i < spec->dac_info_filled; i++) { | ||
4102 | type = spec->dac_info[i].type; | ||
4103 | if (type == AUTO_PIN_LINE_OUT) | ||
4104 | type = spec->autocfg.line_out_type; | ||
4105 | if (type == AUTO_PIN_SPEAKER_OUT) | ||
4106 | num_spk++; | ||
4107 | } | ||
4108 | return (num_spk == 2 && spec->autocfg.line_out_type != AUTO_PIN_LINE_OUT); | ||
4109 | } | ||
4110 | |||
4111 | static int cx_auto_build_output_controls(struct hda_codec *codec) | ||
4112 | { | ||
4113 | struct conexant_spec *spec = codec->spec; | ||
4114 | int i, err; | ||
4115 | int num_line = 0, num_hp = 0, num_spk = 0; | ||
4116 | bool speaker_2_1; | ||
4117 | static const char * const texts[3] = { "Front", "Surround", "CLFE" }; | ||
4118 | |||
4119 | if (spec->dac_info_filled == 1) | ||
4120 | return try_add_pb_volume(codec, spec->dac_info[0].dac, | ||
4121 | spec->dac_info[0].pin, | ||
4122 | "Master", 0); | ||
4123 | |||
4124 | speaker_2_1 = is_2_1_speaker(spec); | ||
4125 | |||
4126 | for (i = 0; i < spec->dac_info_filled; i++) { | ||
4127 | const char *label; | ||
4128 | int idx, type; | ||
4129 | hda_nid_t dac = spec->dac_info[i].dac; | ||
4130 | type = spec->dac_info[i].type; | ||
4131 | if (type == AUTO_PIN_LINE_OUT) | ||
4132 | type = spec->autocfg.line_out_type; | ||
4133 | switch (type) { | ||
4134 | case AUTO_PIN_LINE_OUT: | ||
4135 | default: | ||
4136 | label = texts[num_line++]; | ||
4137 | idx = 0; | ||
4138 | break; | ||
4139 | case AUTO_PIN_HP_OUT: | ||
4140 | label = "Headphone"; | ||
4141 | idx = num_hp++; | ||
4142 | break; | ||
4143 | case AUTO_PIN_SPEAKER_OUT: | ||
4144 | if (speaker_2_1) { | ||
4145 | label = num_spk++ ? "Bass Speaker" : "Speaker"; | ||
4146 | idx = 0; | ||
4147 | } else { | ||
4148 | label = "Speaker"; | ||
4149 | idx = num_spk++; | ||
4150 | } | ||
4151 | break; | ||
4152 | } | ||
4153 | err = try_add_pb_volume(codec, dac, | ||
4154 | spec->dac_info[i].pin, | ||
4155 | label, idx); | ||
4156 | if (err < 0) | ||
4157 | return err; | ||
4158 | } | ||
4159 | |||
4160 | if (spec->auto_mute) { | ||
4161 | err = snd_hda_add_new_ctls(codec, cx_automute_mode_enum); | ||
4162 | if (err < 0) | ||
4163 | return err; | ||
4164 | } | ||
4165 | |||
4166 | return 0; | ||
4167 | } | ||
4168 | |||
4169 | /* Returns zero if this is a normal stereo channel, and non-zero if it should | ||
4170 | be split in two independent channels. | ||
4171 | dest_label must be at least 44 characters. */ | ||
4172 | static int cx_auto_get_rightch_label(struct hda_codec *codec, const char *label, | ||
4173 | char *dest_label, int nid) | ||
4174 | { | ||
4175 | struct conexant_spec *spec = codec->spec; | ||
4176 | int i; | ||
4177 | |||
4178 | if (!spec->fixup_stereo_dmic) | ||
4179 | return 0; | ||
4180 | |||
4181 | for (i = 0; i < AUTO_CFG_MAX_INS; i++) { | ||
4182 | int def_conf; | ||
4183 | if (spec->autocfg.inputs[i].pin != nid) | ||
4184 | continue; | ||
4185 | |||
4186 | if (spec->autocfg.inputs[i].type != AUTO_PIN_MIC) | ||
4187 | return 0; | ||
4188 | def_conf = snd_hda_codec_get_pincfg(codec, nid); | ||
4189 | if (snd_hda_get_input_pin_attr(def_conf) != INPUT_PIN_ATTR_INT) | ||
4190 | return 0; | ||
4191 | |||
4192 | /* Finally found the inverted internal mic! */ | ||
4193 | snprintf(dest_label, 44, "Inverted %s", label); | ||
4194 | return 1; | ||
4195 | } | ||
4196 | return 0; | ||
4197 | } | ||
4198 | |||
4199 | static int cx_auto_add_capture_volume(struct hda_codec *codec, hda_nid_t nid, | ||
4200 | const char *label, const char *pfx, | ||
4201 | int cidx) | ||
4202 | { | ||
4203 | struct conexant_spec *spec = codec->spec; | ||
4204 | int i; | ||
4205 | |||
4206 | for (i = 0; i < spec->num_adc_nids; i++) { | ||
4207 | char rightch_label[44]; | ||
4208 | hda_nid_t adc_nid = spec->adc_nids[i]; | ||
4209 | int idx = get_input_connection(codec, adc_nid, nid); | ||
4210 | if (idx < 0) | ||
4211 | continue; | ||
4212 | if (codec->single_adc_amp) | ||
4213 | idx = 0; | ||
4214 | |||
4215 | if (cx_auto_get_rightch_label(codec, label, rightch_label, nid)) { | ||
4216 | /* Make two independent kcontrols for left and right */ | ||
4217 | int err = cx_auto_add_volume_idx(codec, label, pfx, | ||
4218 | cidx, adc_nid, HDA_INPUT, idx, 1); | ||
4219 | if (err < 0) | ||
4220 | return err; | ||
4221 | return cx_auto_add_volume_idx(codec, rightch_label, pfx, | ||
4222 | cidx, adc_nid, HDA_INPUT, idx, 2); | ||
4223 | } | ||
4224 | return cx_auto_add_volume_idx(codec, label, pfx, | ||
4225 | cidx, adc_nid, HDA_INPUT, idx, 3); | ||
4226 | } | ||
4227 | return 0; | ||
4228 | } | ||
4229 | |||
4230 | static int cx_auto_add_boost_volume(struct hda_codec *codec, int idx, | ||
4231 | const char *label, int cidx) | ||
4232 | { | ||
4233 | struct conexant_spec *spec = codec->spec; | ||
4234 | hda_nid_t mux, nid; | ||
4235 | int i, con; | ||
4236 | |||
4237 | nid = spec->imux_info[idx].pin; | ||
4238 | if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) { | ||
4239 | char rightch_label[44]; | ||
4240 | if (cx_auto_get_rightch_label(codec, label, rightch_label, nid)) { | ||
4241 | int err = cx_auto_add_volume_idx(codec, label, " Boost", | ||
4242 | cidx, nid, HDA_INPUT, 0, 1); | ||
4243 | if (err < 0) | ||
4244 | return err; | ||
4245 | return cx_auto_add_volume_idx(codec, rightch_label, " Boost", | ||
4246 | cidx, nid, HDA_INPUT, 0, 2); | ||
4247 | } | ||
4248 | return cx_auto_add_volume(codec, label, " Boost", cidx, | ||
4249 | nid, HDA_INPUT); | ||
4250 | } | ||
4251 | con = __select_input_connection(codec, spec->imux_info[idx].adc, nid, | ||
4252 | &mux, false, 0); | ||
4253 | if (con < 0) | ||
4254 | return 0; | ||
4255 | for (i = 0; i < idx; i++) { | ||
4256 | if (spec->imux_info[i].boost == mux) | ||
4257 | return 0; /* already present */ | ||
4258 | } | ||
4259 | |||
4260 | if (get_wcaps(codec, mux) & AC_WCAP_OUT_AMP) { | ||
4261 | spec->imux_info[idx].boost = mux; | ||
4262 | return cx_auto_add_volume(codec, label, " Boost", cidx, | ||
4263 | mux, HDA_OUTPUT); | ||
4264 | } | ||
4265 | return 0; | ||
4266 | } | ||
4267 | |||
4268 | static int cx_auto_build_input_controls(struct hda_codec *codec) | ||
4269 | { | ||
4270 | struct conexant_spec *spec = codec->spec; | ||
4271 | struct hda_input_mux *imux = &spec->private_imux; | ||
4272 | const char *prev_label; | ||
4273 | int input_conn[HDA_MAX_NUM_INPUTS]; | ||
4274 | int i, j, err, cidx; | ||
4275 | int multi_connection; | ||
4276 | |||
4277 | if (!imux->num_items) | ||
4278 | return 0; | ||
4279 | |||
4280 | multi_connection = 0; | ||
4281 | for (i = 0; i < imux->num_items; i++) { | ||
4282 | cidx = get_input_connection(codec, spec->imux_info[i].adc, | ||
4283 | spec->imux_info[i].pin); | ||
4284 | if (cidx < 0) | ||
4285 | continue; | ||
4286 | input_conn[i] = spec->imux_info[i].adc; | ||
4287 | if (!codec->single_adc_amp) | ||
4288 | input_conn[i] |= cidx << 8; | ||
4289 | if (i > 0 && input_conn[i] != input_conn[0]) | ||
4290 | multi_connection = 1; | ||
4291 | } | ||
4292 | |||
4293 | prev_label = NULL; | ||
4294 | cidx = 0; | ||
4295 | for (i = 0; i < imux->num_items; i++) { | ||
4296 | hda_nid_t nid = spec->imux_info[i].pin; | ||
4297 | const char *label; | ||
4298 | |||
4299 | label = hda_get_autocfg_input_label(codec, &spec->autocfg, | ||
4300 | spec->imux_info[i].index); | ||
4301 | if (label == prev_label) | ||
4302 | cidx++; | ||
4303 | else | ||
4304 | cidx = 0; | ||
4305 | prev_label = label; | ||
4306 | |||
4307 | err = cx_auto_add_boost_volume(codec, i, label, cidx); | ||
4308 | if (err < 0) | ||
4309 | return err; | ||
4310 | |||
4311 | if (!multi_connection) { | ||
4312 | if (i > 0) | ||
4313 | continue; | ||
4314 | err = cx_auto_add_capture_volume(codec, nid, | ||
4315 | "Capture", "", cidx); | ||
4316 | } else { | ||
4317 | bool dup_found = false; | ||
4318 | for (j = 0; j < i; j++) { | ||
4319 | if (input_conn[j] == input_conn[i]) { | ||
4320 | dup_found = true; | ||
4321 | break; | ||
4322 | } | ||
4323 | } | ||
4324 | if (dup_found) | ||
4325 | continue; | ||
4326 | err = cx_auto_add_capture_volume(codec, nid, | ||
4327 | label, " Capture", cidx); | ||
4328 | } | ||
4329 | if (err < 0) | ||
4330 | return err; | ||
4331 | } | ||
4332 | |||
4333 | if (spec->private_imux.num_items > 1 && !spec->auto_mic) { | ||
4334 | err = snd_hda_add_new_ctls(codec, cx_auto_capture_mixers); | ||
4335 | if (err < 0) | ||
4336 | return err; | ||
4337 | } | ||
4338 | |||
4339 | return 0; | ||
4340 | } | ||
4341 | |||
4342 | static int cx_auto_build_controls(struct hda_codec *codec) | 3179 | static int cx_auto_build_controls(struct hda_codec *codec) |
4343 | { | 3180 | { |
4344 | struct conexant_spec *spec = codec->spec; | ||
4345 | int err; | 3181 | int err; |
4346 | 3182 | ||
4347 | err = cx_auto_build_output_controls(codec); | 3183 | err = snd_hda_gen_build_controls(codec); |
4348 | if (err < 0) | 3184 | if (err < 0) |
4349 | return err; | 3185 | return err; |
4350 | err = cx_auto_build_input_controls(codec); | 3186 | |
4351 | if (err < 0) | 3187 | err = add_beep_ctls(codec); |
4352 | return err; | ||
4353 | err = conexant_build_controls(codec); | ||
4354 | if (err < 0) | ||
4355 | return err; | ||
4356 | err = snd_hda_jack_add_kctls(codec, &spec->autocfg); | ||
4357 | if (err < 0) | 3188 | if (err < 0) |
4358 | return err; | 3189 | return err; |
4359 | if (spec->vmaster_mute.sw_kctl) { | ||
4360 | spec->vmaster_mute.hook = cx_auto_vmaster_hook; | ||
4361 | err = snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute, | ||
4362 | spec->vmaster_mute_led); | ||
4363 | if (err < 0) | ||
4364 | return err; | ||
4365 | } | ||
4366 | return 0; | ||
4367 | } | ||
4368 | 3190 | ||
4369 | static int cx_auto_search_adcs(struct hda_codec *codec) | ||
4370 | { | ||
4371 | struct conexant_spec *spec = codec->spec; | ||
4372 | hda_nid_t nid, end_nid; | ||
4373 | |||
4374 | end_nid = codec->start_nid + codec->num_nodes; | ||
4375 | for (nid = codec->start_nid; nid < end_nid; nid++) { | ||
4376 | unsigned int caps = get_wcaps(codec, nid); | ||
4377 | if (get_wcaps_type(caps) != AC_WID_AUD_IN) | ||
4378 | continue; | ||
4379 | if (caps & AC_WCAP_DIGITAL) | ||
4380 | continue; | ||
4381 | if (snd_BUG_ON(spec->num_adc_nids >= | ||
4382 | ARRAY_SIZE(spec->private_adc_nids))) | ||
4383 | break; | ||
4384 | spec->private_adc_nids[spec->num_adc_nids++] = nid; | ||
4385 | } | ||
4386 | spec->adc_nids = spec->private_adc_nids; | ||
4387 | return 0; | 3191 | return 0; |
4388 | } | 3192 | } |
4389 | 3193 | ||
4390 | static const struct hda_codec_ops cx_auto_patch_ops = { | 3194 | static const struct hda_codec_ops cx_auto_patch_ops = { |
4391 | .build_controls = cx_auto_build_controls, | 3195 | .build_controls = cx_auto_build_controls, |
4392 | .build_pcms = conexant_build_pcms, | 3196 | .build_pcms = snd_hda_gen_build_pcms, |
4393 | .init = cx_auto_init, | 3197 | .init = snd_hda_gen_init, |
4394 | .free = conexant_free, | 3198 | .free = snd_hda_gen_free, |
4395 | .unsol_event = snd_hda_jack_unsol_event, | 3199 | .unsol_event = snd_hda_jack_unsol_event, |
3200 | #ifdef CONFIG_PM | ||
3201 | .check_power_status = snd_hda_gen_check_power_status, | ||
3202 | #endif | ||
4396 | }; | 3203 | }; |
4397 | 3204 | ||
4398 | /* | 3205 | /* |
@@ -4411,7 +3218,7 @@ static void cxt_fixup_stereo_dmic(struct hda_codec *codec, | |||
4411 | const struct hda_fixup *fix, int action) | 3218 | const struct hda_fixup *fix, int action) |
4412 | { | 3219 | { |
4413 | struct conexant_spec *spec = codec->spec; | 3220 | struct conexant_spec *spec = codec->spec; |
4414 | spec->fixup_stereo_dmic = 1; | 3221 | spec->gen.inv_dmic_split = 1; |
4415 | } | 3222 | } |
4416 | 3223 | ||
4417 | static void cxt5066_increase_mic_boost(struct hda_codec *codec, | 3224 | static void cxt5066_increase_mic_boost(struct hda_codec *codec, |
@@ -4532,13 +3339,22 @@ static int patch_conexant_auto(struct hda_codec *codec) | |||
4532 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 3339 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
4533 | if (!spec) | 3340 | if (!spec) |
4534 | return -ENOMEM; | 3341 | return -ENOMEM; |
3342 | snd_hda_gen_spec_init(&spec->gen); | ||
4535 | codec->spec = spec; | 3343 | codec->spec = spec; |
4536 | snd_hda_gen_init(&spec->gen); | 3344 | |
3345 | cx_auto_parse_beep(codec); | ||
3346 | cx_auto_parse_eapd(codec); | ||
3347 | if (spec->gen.own_eapd_ctl) | ||
3348 | spec->gen.vmaster_mute.hook = cx_auto_vmaster_hook; | ||
4537 | 3349 | ||
4538 | switch (codec->vendor_id) { | 3350 | switch (codec->vendor_id) { |
4539 | case 0x14f15045: | 3351 | case 0x14f15045: |
4540 | codec->single_adc_amp = 1; | 3352 | codec->single_adc_amp = 1; |
4541 | break; | 3353 | break; |
3354 | case 0x14f15047: | ||
3355 | codec->pin_amp_workaround = 1; | ||
3356 | spec->gen.mixer_nid = 0x19; | ||
3357 | break; | ||
4542 | case 0x14f15051: | 3358 | case 0x14f15051: |
4543 | add_cx5051_fake_mutes(codec); | 3359 | add_cx5051_fake_mutes(codec); |
4544 | codec->pin_amp_workaround = 1; | 3360 | codec->pin_amp_workaround = 1; |
@@ -4550,8 +3366,6 @@ static int patch_conexant_auto(struct hda_codec *codec) | |||
4550 | break; | 3366 | break; |
4551 | } | 3367 | } |
4552 | 3368 | ||
4553 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | ||
4554 | |||
4555 | /* Show mute-led control only on HP laptops | 3369 | /* Show mute-led control only on HP laptops |
4556 | * This is a sort of white-list: on HP laptops, EAPD corresponds | 3370 | * This is a sort of white-list: on HP laptops, EAPD corresponds |
4557 | * only to the mute-LED without actualy amp function. Meanwhile, | 3371 | * only to the mute-LED without actualy amp function. Meanwhile, |
@@ -4560,20 +3374,20 @@ static int patch_conexant_auto(struct hda_codec *codec) | |||
4560 | */ | 3374 | */ |
4561 | switch (codec->subsystem_id >> 16) { | 3375 | switch (codec->subsystem_id >> 16) { |
4562 | case 0x103c: | 3376 | case 0x103c: |
4563 | spec->vmaster_mute_led = 1; | 3377 | spec->gen.vmaster_mute_enum = 1; |
4564 | break; | 3378 | break; |
4565 | } | 3379 | } |
4566 | 3380 | ||
4567 | err = cx_auto_search_adcs(codec); | 3381 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
3382 | |||
3383 | err = snd_hda_parse_pin_defcfg(codec, &spec->gen.autocfg, NULL, 0); | ||
4568 | if (err < 0) | 3384 | if (err < 0) |
4569 | return err; | 3385 | goto error; |
4570 | err = cx_auto_parse_auto_config(codec); | 3386 | |
4571 | if (err < 0) { | 3387 | err = snd_hda_gen_parse_auto_config(codec, &spec->gen.autocfg); |
4572 | kfree(codec->spec); | 3388 | if (err < 0) |
4573 | codec->spec = NULL; | 3389 | goto error; |
4574 | return err; | 3390 | |
4575 | } | ||
4576 | spec->capture_stream = &cx_auto_pcm_analog_capture; | ||
4577 | codec->patch_ops = cx_auto_patch_ops; | 3391 | codec->patch_ops = cx_auto_patch_ops; |
4578 | if (spec->beep_amp) | 3392 | if (spec->beep_amp) |
4579 | snd_hda_attach_beep_device(codec, spec->beep_amp); | 3393 | snd_hda_attach_beep_device(codec, spec->beep_amp); |
@@ -4590,8 +3404,19 @@ static int patch_conexant_auto(struct hda_codec *codec) | |||
4590 | } | 3404 | } |
4591 | 3405 | ||
4592 | return 0; | 3406 | return 0; |
3407 | |||
3408 | error: | ||
3409 | snd_hda_gen_free(codec); | ||
3410 | return err; | ||
4593 | } | 3411 | } |
4594 | 3412 | ||
3413 | #ifndef ENABLE_CXT_STATIC_QUIRKS | ||
3414 | #define patch_cxt5045 patch_conexant_auto | ||
3415 | #define patch_cxt5047 patch_conexant_auto | ||
3416 | #define patch_cxt5051 patch_conexant_auto | ||
3417 | #define patch_cxt5066 patch_conexant_auto | ||
3418 | #endif | ||
3419 | |||
4595 | /* | 3420 | /* |
4596 | */ | 3421 | */ |
4597 | 3422 | ||