diff options
author | Takashi Iwai <tiwai@suse.de> | 2012-03-12 07:38:51 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2012-03-12 09:52:43 -0400 |
commit | 527c73bada6f02a35983ddb34db3a0fd4360c88c (patch) | |
tree | f87f67a3e9df1aa08f251fb0d7e7c6f40f0dcf35 /sound/pci | |
parent | 420b0febe54099ea9003bddad0a81e882a8472af (diff) |
ALSA: hda - Add EAPD control to Conexnat auto-parser
Added the vmaster hook for controlling EAPD dynamically to Conexant
auto-parser. When the Master is muted, EAPDs are turned off as well.
This will fix the missing mute-LED control on some machines in
addition to the more power-saving in the auto-parser mode.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/hda/patch_conexant.c | 36 |
1 files changed, 32 insertions, 4 deletions
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 5a56fda83625..f1c9aed9fa69 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -70,6 +70,8 @@ struct conexant_spec { | |||
70 | const struct snd_kcontrol_new *mixers[5]; | 70 | const struct snd_kcontrol_new *mixers[5]; |
71 | int num_mixers; | 71 | int num_mixers; |
72 | hda_nid_t vmaster_nid; | 72 | hda_nid_t vmaster_nid; |
73 | struct snd_kcontrol *vmaster_sw_kctl; | ||
74 | void (*vmaster_hook)(struct snd_kcontrol *, int); | ||
73 | 75 | ||
74 | const struct hda_verb *init_verbs[5]; /* initialization verbs | 76 | const struct hda_verb *init_verbs[5]; /* initialization verbs |
75 | * don't forget NULL | 77 | * don't forget NULL |
@@ -513,9 +515,10 @@ static int conexant_build_controls(struct hda_codec *codec) | |||
513 | } | 515 | } |
514 | if (spec->vmaster_nid && | 516 | if (spec->vmaster_nid && |
515 | !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { | 517 | !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { |
516 | err = snd_hda_add_vmaster(codec, "Master Playback Switch", | 518 | err = __snd_hda_add_vmaster(codec, "Master Playback Switch", |
517 | NULL, slave_pfxs, | 519 | NULL, slave_pfxs, |
518 | "Playback Switch"); | 520 | "Playback Switch", true, |
521 | &spec->vmaster_sw_kctl); | ||
519 | if (err < 0) | 522 | if (err < 0) |
520 | return err; | 523 | return err; |
521 | } | 524 | } |
@@ -3975,6 +3978,19 @@ static void clear_unsol_on_unused_pins(struct hda_codec *codec) | |||
3975 | } | 3978 | } |
3976 | } | 3979 | } |
3977 | 3980 | ||
3981 | /* turn on/off EAPD according to Master switch */ | ||
3982 | static void cx_auto_vmaster_hook(void *private_data, int enabled) | ||
3983 | { | ||
3984 | struct hda_codec *codec = private_data; | ||
3985 | struct conexant_spec *spec = codec->spec; | ||
3986 | |||
3987 | if (enabled && spec->pin_eapd_ctrls) { | ||
3988 | cx_auto_update_speakers(codec); | ||
3989 | return; | ||
3990 | } | ||
3991 | cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, enabled); | ||
3992 | } | ||
3993 | |||
3978 | static void cx_auto_init_output(struct hda_codec *codec) | 3994 | static void cx_auto_init_output(struct hda_codec *codec) |
3979 | { | 3995 | { |
3980 | struct conexant_spec *spec = codec->spec; | 3996 | struct conexant_spec *spec = codec->spec; |
@@ -4079,11 +4095,13 @@ static void cx_auto_init_digital(struct hda_codec *codec) | |||
4079 | 4095 | ||
4080 | static int cx_auto_init(struct hda_codec *codec) | 4096 | static int cx_auto_init(struct hda_codec *codec) |
4081 | { | 4097 | { |
4098 | struct conexant_spec *spec = codec->spec; | ||
4082 | /*snd_hda_sequence_write(codec, cx_auto_init_verbs);*/ | 4099 | /*snd_hda_sequence_write(codec, cx_auto_init_verbs);*/ |
4083 | cx_auto_init_output(codec); | 4100 | cx_auto_init_output(codec); |
4084 | cx_auto_init_input(codec); | 4101 | cx_auto_init_input(codec); |
4085 | cx_auto_init_digital(codec); | 4102 | cx_auto_init_digital(codec); |
4086 | snd_hda_jack_report_sync(codec); | 4103 | snd_hda_jack_report_sync(codec); |
4104 | snd_ctl_sync_vmaster_hook(spec->vmaster_sw_kctl); | ||
4087 | return 0; | 4105 | return 0; |
4088 | } | 4106 | } |
4089 | 4107 | ||
@@ -4329,6 +4347,11 @@ static int cx_auto_build_controls(struct hda_codec *codec) | |||
4329 | err = snd_hda_jack_add_kctls(codec, &spec->autocfg); | 4347 | err = snd_hda_jack_add_kctls(codec, &spec->autocfg); |
4330 | if (err < 0) | 4348 | if (err < 0) |
4331 | return err; | 4349 | return err; |
4350 | if (spec->vmaster_hook && spec->vmaster_sw_kctl) { | ||
4351 | snd_ctl_add_vmaster_hook(spec->vmaster_sw_kctl, | ||
4352 | spec->vmaster_hook, codec); | ||
4353 | snd_ctl_sync_vmaster_hook(spec->vmaster_sw_kctl); | ||
4354 | } | ||
4332 | return 0; | 4355 | return 0; |
4333 | } | 4356 | } |
4334 | 4357 | ||
@@ -4353,7 +4376,6 @@ static int cx_auto_search_adcs(struct hda_codec *codec) | |||
4353 | return 0; | 4376 | return 0; |
4354 | } | 4377 | } |
4355 | 4378 | ||
4356 | |||
4357 | static const struct hda_codec_ops cx_auto_patch_ops = { | 4379 | static const struct hda_codec_ops cx_auto_patch_ops = { |
4358 | .build_controls = cx_auto_build_controls, | 4380 | .build_controls = cx_auto_build_controls, |
4359 | .build_pcms = conexant_build_pcms, | 4381 | .build_pcms = conexant_build_pcms, |
@@ -4455,6 +4477,12 @@ static int patch_conexant_auto(struct hda_codec *codec) | |||
4455 | 4477 | ||
4456 | apply_pin_fixup(codec, cxt_fixups, cxt_pincfg_tbl); | 4478 | apply_pin_fixup(codec, cxt_fixups, cxt_pincfg_tbl); |
4457 | 4479 | ||
4480 | /* add EAPD vmaster hook to all HP machines */ | ||
4481 | /* NOTE: this should be applied via fixup once when the generic | ||
4482 | * fixup code is merged to hda_codec.c | ||
4483 | */ | ||
4484 | spec->vmaster_hook = cx_auto_vmaster_hook; | ||
4485 | |||
4458 | err = cx_auto_search_adcs(codec); | 4486 | err = cx_auto_search_adcs(codec); |
4459 | if (err < 0) | 4487 | if (err < 0) |
4460 | return err; | 4488 | return err; |