aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2011-07-11 08:46:44 -0400
committerTakashi Iwai <tiwai@suse.de>2011-07-11 08:46:44 -0400
commit19110595c89b2d606883b7cb99260c7e47fd2143 (patch)
tree23dab5766568b51cbe223f53c82fd2446055807b /sound/pci/hda
parent9499473463628a1af4be5aea1ad8d35d3fd341b0 (diff)
ALSA: hda - Turn on extra EAPDs on Conexant codecs
Some machines seem to use EAPD control of the unused pin for controlling the overall EAPD. Since the driver currently doesn't check the EAPD of unused pins, the EAPD isn't enabled. For avoiding such a problem, turn all extra EAPDs on as default. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda')
-rw-r--r--sound/pci/hda/patch_conexant.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 4ca880bb68fa..884f67b8f4e0 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -155,6 +155,10 @@ struct conexant_spec {
155 unsigned int mic_boost; /* offset into cxt5066_analog_mic_boost */ 155 unsigned int mic_boost; /* offset into cxt5066_analog_mic_boost */
156 156
157 unsigned int beep_amp; 157 unsigned int beep_amp;
158
159 /* extra EAPD pins */
160 unsigned int num_eapds;
161 hda_nid_t eapds[4];
158}; 162};
159 163
160static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo, 164static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo,
@@ -3901,6 +3905,38 @@ static void cx_auto_parse_beep(struct hda_codec *codec)
3901#define cx_auto_parse_beep(codec) 3905#define cx_auto_parse_beep(codec)
3902#endif 3906#endif
3903 3907
3908static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
3909{
3910 int i;
3911 for (i = 0; i < nums; i++)
3912 if (list[i] == nid)
3913 return true;
3914 return false;
3915}
3916
3917/* parse extra-EAPD that aren't assigned to any pins */
3918static void cx_auto_parse_eapd(struct hda_codec *codec)
3919{
3920 struct conexant_spec *spec = codec->spec;
3921 struct auto_pin_cfg *cfg = &spec->autocfg;
3922 hda_nid_t nid, end_nid;
3923
3924 end_nid = codec->start_nid + codec->num_nodes;
3925 for (nid = codec->start_nid; nid < end_nid; nid++) {
3926 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
3927 continue;
3928 if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD))
3929 continue;
3930 if (found_in_nid_list(nid, cfg->line_out_pins, cfg->line_outs) ||
3931 found_in_nid_list(nid, cfg->hp_pins, cfg->hp_outs) ||
3932 found_in_nid_list(nid, cfg->speaker_pins, cfg->speaker_outs))
3933 continue;
3934 spec->eapds[spec->num_eapds++] = nid;
3935 if (spec->num_eapds >= ARRAY_SIZE(spec->eapds))
3936 break;
3937 }
3938}
3939
3904static int cx_auto_parse_auto_config(struct hda_codec *codec) 3940static int cx_auto_parse_auto_config(struct hda_codec *codec)
3905{ 3941{
3906 struct conexant_spec *spec = codec->spec; 3942 struct conexant_spec *spec = codec->spec;
@@ -3914,6 +3950,7 @@ static int cx_auto_parse_auto_config(struct hda_codec *codec)
3914 cx_auto_parse_input(codec); 3950 cx_auto_parse_input(codec);
3915 cx_auto_parse_digital(codec); 3951 cx_auto_parse_digital(codec);
3916 cx_auto_parse_beep(codec); 3952 cx_auto_parse_beep(codec);
3953 cx_auto_parse_eapd(codec);
3917 return 0; 3954 return 0;
3918} 3955}
3919 3956
@@ -4001,6 +4038,8 @@ static void cx_auto_init_output(struct hda_codec *codec)
4001 } 4038 }
4002 } 4039 }
4003 cx_auto_update_speakers(codec); 4040 cx_auto_update_speakers(codec);
4041 /* turn on/off extra EAPDs, too */
4042 cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true);
4004} 4043}
4005 4044
4006static void cx_auto_init_input(struct hda_codec *codec) 4045static void cx_auto_init_input(struct hda_codec *codec)