aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2011-10-14 09:22:34 -0400
committerTakashi Iwai <tiwai@suse.de>2011-10-27 10:58:10 -0400
commit254f296840b64b034a4c850d45dbde7c040f0819 (patch)
tree0341a73271adc08dd7fc6e654e46e23682cca081 /sound
parent527e4d73af16dfc35a770dfdc3874ef63c359ea6 (diff)
ALSA: hda - Keep EAPD turned on for old Conexant chips
In the old Conexant chips (5045, 5047, 5051 and 5066), a single EAPD may handle both headphone and speaker outputs while it's assigned only to one of them. Turning off dynamically leads to the unexpected silent output in such a configuration with the auto-mute function. Since it's difficult to know how the EAPD is handled in the actual h/w implementation, better to keep EAPD on while running for such codecs. Cc: <stable@kernel.org> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/hda/patch_conexant.c43
1 files changed, 22 insertions, 21 deletions
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 686ec6d75c6..1d69a3e0ce2 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -136,6 +136,7 @@ struct conexant_spec {
136 unsigned int thinkpad:1; 136 unsigned int thinkpad:1;
137 unsigned int hp_laptop:1; 137 unsigned int hp_laptop:1;
138 unsigned int asus:1; 138 unsigned int asus:1;
139 unsigned int pin_eapd_ctrls:1;
139 140
140 unsigned int adc_switching:1; 141 unsigned int adc_switching:1;
141 142
@@ -3430,12 +3431,14 @@ static void cx_auto_turn_eapd(struct hda_codec *codec, int num_pins,
3430static void do_automute(struct hda_codec *codec, int num_pins, 3431static void do_automute(struct hda_codec *codec, int num_pins,
3431 hda_nid_t *pins, bool on) 3432 hda_nid_t *pins, bool on)
3432{ 3433{
3434 struct conexant_spec *spec = codec->spec;
3433 int i; 3435 int i;
3434 for (i = 0; i < num_pins; i++) 3436 for (i = 0; i < num_pins; i++)
3435 snd_hda_codec_write(codec, pins[i], 0, 3437 snd_hda_codec_write(codec, pins[i], 0,
3436 AC_VERB_SET_PIN_WIDGET_CONTROL, 3438 AC_VERB_SET_PIN_WIDGET_CONTROL,
3437 on ? PIN_OUT : 0); 3439 on ? PIN_OUT : 0);
3438 cx_auto_turn_eapd(codec, num_pins, pins, on); 3440 if (spec->pin_eapd_ctrls)
3441 cx_auto_turn_eapd(codec, num_pins, pins, on);
3439} 3442}
3440 3443
3441static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins) 3444static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
@@ -3460,9 +3463,12 @@ static void cx_auto_update_speakers(struct hda_codec *codec)
3460 int on = 1; 3463 int on = 1;
3461 3464
3462 /* turn on HP EAPD when HP jacks are present */ 3465 /* turn on HP EAPD when HP jacks are present */
3463 if (spec->auto_mute) 3466 if (spec->pin_eapd_ctrls) {
3464 on = spec->hp_present; 3467 if (spec->auto_mute)
3465 cx_auto_turn_eapd(codec, cfg->hp_outs, cfg->hp_pins, on); 3468 on = spec->hp_present;
3469 cx_auto_turn_eapd(codec, cfg->hp_outs, cfg->hp_pins, on);
3470 }
3471
3466 /* mute speakers in auto-mode if HP or LO jacks are plugged */ 3472 /* mute speakers in auto-mode if HP or LO jacks are plugged */
3467 if (spec->auto_mute) 3473 if (spec->auto_mute)
3468 on = !(spec->hp_present || 3474 on = !(spec->hp_present ||
@@ -3889,20 +3895,10 @@ static void cx_auto_parse_beep(struct hda_codec *codec)
3889#define cx_auto_parse_beep(codec) 3895#define cx_auto_parse_beep(codec)
3890#endif 3896#endif
3891 3897
3892static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) 3898/* parse EAPDs */
3893{
3894 int i;
3895 for (i = 0; i < nums; i++)
3896 if (list[i] == nid)
3897 return true;
3898 return false;
3899}
3900
3901/* parse extra-EAPD that aren't assigned to any pins */
3902static void cx_auto_parse_eapd(struct hda_codec *codec) 3899static void cx_auto_parse_eapd(struct hda_codec *codec)
3903{ 3900{
3904 struct conexant_spec *spec = codec->spec; 3901 struct conexant_spec *spec = codec->spec;
3905 struct auto_pin_cfg *cfg = &spec->autocfg;
3906 hda_nid_t nid, end_nid; 3902 hda_nid_t nid, end_nid;
3907 3903
3908 end_nid = codec->start_nid + codec->num_nodes; 3904 end_nid = codec->start_nid + codec->num_nodes;
@@ -3911,14 +3907,18 @@ static void cx_auto_parse_eapd(struct hda_codec *codec)
3911 continue; 3907 continue;
3912 if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)) 3908 if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD))
3913 continue; 3909 continue;
3914 if (found_in_nid_list(nid, cfg->line_out_pins, cfg->line_outs) ||
3915 found_in_nid_list(nid, cfg->hp_pins, cfg->hp_outs) ||
3916 found_in_nid_list(nid, cfg->speaker_pins, cfg->speaker_outs))
3917 continue;
3918 spec->eapds[spec->num_eapds++] = nid; 3910 spec->eapds[spec->num_eapds++] = nid;
3919 if (spec->num_eapds >= ARRAY_SIZE(spec->eapds)) 3911 if (spec->num_eapds >= ARRAY_SIZE(spec->eapds))
3920 break; 3912 break;
3921 } 3913 }
3914
3915 /* NOTE: below is a wild guess; if we have more than two EAPDs,
3916 * it's a new chip, where EAPDs are supposed to be associated to
3917 * pins, and we can control EAPD per pin.
3918 * OTOH, if only one or two EAPDs are found, it's an old chip,
3919 * thus it might control over all pins.
3920 */
3921 spec->pin_eapd_ctrls = spec->num_eapds > 2;
3922} 3922}
3923 3923
3924static int cx_auto_parse_auto_config(struct hda_codec *codec) 3924static int cx_auto_parse_auto_config(struct hda_codec *codec)
@@ -4024,8 +4024,9 @@ static void cx_auto_init_output(struct hda_codec *codec)
4024 } 4024 }
4025 } 4025 }
4026 cx_auto_update_speakers(codec); 4026 cx_auto_update_speakers(codec);
4027 /* turn on/off extra EAPDs, too */ 4027 /* turn on all EAPDs if no individual EAPD control is available */
4028 cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true); 4028 if (!spec->pin_eapd_ctrls)
4029 cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true);
4029} 4030}
4030 4031
4031static void cx_auto_init_input(struct hda_codec *codec) 4032static void cx_auto_init_input(struct hda_codec *codec)