aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2012-03-12 07:38:51 -0400
committerTakashi Iwai <tiwai@suse.de>2012-03-12 09:52:43 -0400
commit527c73bada6f02a35983ddb34db3a0fd4360c88c (patch)
treef87f67a3e9df1aa08f251fb0d7e7c6f40f0dcf35 /sound/pci
parent420b0febe54099ea9003bddad0a81e882a8472af (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.c36
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 */
3982static 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
3978static void cx_auto_init_output(struct hda_codec *codec) 3994static 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
4080static int cx_auto_init(struct hda_codec *codec) 4096static 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
4357static const struct hda_codec_ops cx_auto_patch_ops = { 4379static 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;