aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_ca0132.c
diff options
context:
space:
mode:
authorChih-Chung Chang <chihchung@chromium.org>2013-03-25 13:39:23 -0400
committerTakashi Iwai <tiwai@suse.de>2013-04-02 05:28:39 -0400
commit993884f6a26c6547fa3875f9d3fabdc4250d8da6 (patch)
tree8852dd8068a9dd332fe435fedee1891f60dca17d /sound/pci/hda/patch_ca0132.c
parentb8e63df919d75ef4ecafd66b5123a798b18cc0e7 (diff)
ALSA: hda/ca0132 - Delay HP amp turnon.
Turing on the headphone amp interferes with the impedance measurement used to detect a TRRS style headset microphone. Delay the HP turn on until 500ms after the jack is detected, allowing the mic detection state machine to run to completion. Signed-off-by: Chih-Chung Chang <chihchung@chromium.org> Signed-off-by: Dylan Reid <dgreid@chromium.org> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/patch_ca0132.c')
-rw-r--r--sound/pci/hda/patch_ca0132.c27
1 files changed, 23 insertions, 4 deletions
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 0792b5725f9c..12eb21aff557 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -741,6 +741,9 @@ struct ca0132_spec {
741 long voicefx_val; 741 long voicefx_val;
742 long cur_mic_boost; 742 long cur_mic_boost;
743 743
744 struct hda_codec *codec;
745 struct delayed_work unsol_hp_work;
746
744#ifdef ENABLE_TUNING_CONTROLS 747#ifdef ENABLE_TUNING_CONTROLS
745 long cur_ctl_vals[TUNING_CTLS_COUNT]; 748 long cur_ctl_vals[TUNING_CTLS_COUNT];
746#endif 749#endif
@@ -3227,6 +3230,14 @@ exit:
3227 return err < 0 ? err : 0; 3230 return err < 0 ? err : 0;
3228} 3231}
3229 3232
3233static void ca0132_unsol_hp_delayed(struct work_struct *work)
3234{
3235 struct ca0132_spec *spec = container_of(
3236 to_delayed_work(work), struct ca0132_spec, unsol_hp_work);
3237 ca0132_select_out(spec->codec);
3238 snd_hda_jack_report_sync(spec->codec);
3239}
3240
3230static void ca0132_set_dmic(struct hda_codec *codec, int enable); 3241static void ca0132_set_dmic(struct hda_codec *codec, int enable);
3231static int ca0132_mic_boost_set(struct hda_codec *codec, long val); 3242static int ca0132_mic_boost_set(struct hda_codec *codec, long val);
3232static int ca0132_effects_set(struct hda_codec *codec, hda_nid_t nid, long val); 3243static int ca0132_effects_set(struct hda_codec *codec, hda_nid_t nid, long val);
@@ -4399,8 +4410,7 @@ static void ca0132_process_dsp_response(struct hda_codec *codec)
4399 4410
4400static void ca0132_unsol_event(struct hda_codec *codec, unsigned int res) 4411static void ca0132_unsol_event(struct hda_codec *codec, unsigned int res)
4401{ 4412{
4402 snd_printdd(KERN_INFO "ca0132_unsol_event: 0x%x\n", res); 4413 struct ca0132_spec *spec = codec->spec;
4403
4404 4414
4405 if (((res >> AC_UNSOL_RES_TAG_SHIFT) & 0x3f) == UNSOL_TAG_DSP) { 4415 if (((res >> AC_UNSOL_RES_TAG_SHIFT) & 0x3f) == UNSOL_TAG_DSP) {
4406 ca0132_process_dsp_response(codec); 4416 ca0132_process_dsp_response(codec);
@@ -4412,8 +4422,13 @@ static void ca0132_unsol_event(struct hda_codec *codec, unsigned int res)
4412 4422
4413 switch (res) { 4423 switch (res) {
4414 case UNSOL_TAG_HP: 4424 case UNSOL_TAG_HP:
4415 ca0132_select_out(codec); 4425 /* Delay enabling the HP amp, to let the mic-detection
4416 snd_hda_jack_report_sync(codec); 4426 * state machine run.
4427 */
4428 cancel_delayed_work_sync(&spec->unsol_hp_work);
4429 queue_delayed_work(codec->bus->workq,
4430 &spec->unsol_hp_work,
4431 msecs_to_jiffies(500));
4417 break; 4432 break;
4418 case UNSOL_TAG_AMIC1: 4433 case UNSOL_TAG_AMIC1:
4419 ca0132_select_mic(codec); 4434 ca0132_select_mic(codec);
@@ -4588,6 +4603,7 @@ static void ca0132_free(struct hda_codec *codec)
4588{ 4603{
4589 struct ca0132_spec *spec = codec->spec; 4604 struct ca0132_spec *spec = codec->spec;
4590 4605
4606 cancel_delayed_work_sync(&spec->unsol_hp_work);
4591 snd_hda_power_up(codec); 4607 snd_hda_power_up(codec);
4592 snd_hda_sequence_write(codec, spec->base_exit_verbs); 4608 snd_hda_sequence_write(codec, spec->base_exit_verbs);
4593 ca0132_exit_chip(codec); 4609 ca0132_exit_chip(codec);
@@ -4653,6 +4669,7 @@ static int patch_ca0132(struct hda_codec *codec)
4653 if (!spec) 4669 if (!spec)
4654 return -ENOMEM; 4670 return -ENOMEM;
4655 codec->spec = spec; 4671 codec->spec = spec;
4672 spec->codec = codec;
4656 4673
4657 spec->num_mixers = 1; 4674 spec->num_mixers = 1;
4658 spec->mixers[0] = ca0132_mixer; 4675 spec->mixers[0] = ca0132_mixer;
@@ -4663,6 +4680,8 @@ static int patch_ca0132(struct hda_codec *codec)
4663 spec->init_verbs[1] = ca0132_init_verbs1; 4680 spec->init_verbs[1] = ca0132_init_verbs1;
4664 spec->num_init_verbs = 2; 4681 spec->num_init_verbs = 2;
4665 4682
4683 INIT_DELAYED_WORK(&spec->unsol_hp_work, ca0132_unsol_hp_delayed);
4684
4666 ca0132_init_chip(codec); 4685 ca0132_init_chip(codec);
4667 4686
4668 ca0132_config(codec); 4687 ca0132_config(codec);