aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2014-09-11 09:53:26 -0400
committerTakashi Iwai <tiwai@suse.de>2014-09-16 11:25:02 -0400
commitf8fb117034847634bff8f02632151f7535981fa1 (patch)
tree286e991990ab7c832825a0d6cea9e72d63b1e132
parent7c3008c47b405420bf2b24fb5a21af3df5b5c323 (diff)
ALSA: hda - Use standard hda_jack infrastructure for CA0132 driver
For its headphone, mic and DSP responses, we can use the standard hda_jack infrastructure in CA0132 driver, too. The only point to handle carefully is the delayed headphone jack handling. It tries to react after a certain delay. Here we use the existing block_report flag in hda_jack_tbl (that was implemented for HDMI). Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/pci/hda/patch_ca0132.c76
1 files changed, 34 insertions, 42 deletions
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 39fae52258f0..4f7ffa8c4a0d 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -3224,8 +3224,14 @@ static void ca0132_unsol_hp_delayed(struct work_struct *work)
3224{ 3224{
3225 struct ca0132_spec *spec = container_of( 3225 struct ca0132_spec *spec = container_of(
3226 to_delayed_work(work), struct ca0132_spec, unsol_hp_work); 3226 to_delayed_work(work), struct ca0132_spec, unsol_hp_work);
3227 struct hda_jack_tbl *jack;
3228
3227 ca0132_select_out(spec->codec); 3229 ca0132_select_out(spec->codec);
3228 snd_hda_jack_report_sync(spec->codec); 3230 jack = snd_hda_jack_tbl_get(spec->codec, UNSOL_TAG_HP);
3231 if (jack) {
3232 jack->block_report = 0;
3233 snd_hda_jack_report_sync(spec->codec);
3234 }
3229} 3235}
3230 3236
3231static void ca0132_set_dmic(struct hda_codec *codec, int enable); 3237static void ca0132_set_dmic(struct hda_codec *codec, int enable);
@@ -4114,12 +4120,6 @@ static void init_input(struct hda_codec *codec, hda_nid_t pin, hda_nid_t adc)
4114 } 4120 }
4115} 4121}
4116 4122
4117static void ca0132_init_unsol(struct hda_codec *codec)
4118{
4119 snd_hda_jack_detect_enable(codec, UNSOL_TAG_HP);
4120 snd_hda_jack_detect_enable(codec, UNSOL_TAG_AMIC1);
4121}
4122
4123static void refresh_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir) 4123static void refresh_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir)
4124{ 4124{
4125 unsigned int caps; 4125 unsigned int caps;
@@ -4390,7 +4390,8 @@ static void ca0132_download_dsp(struct hda_codec *codec)
4390 ca0132_set_dsp_msr(codec, true); 4390 ca0132_set_dsp_msr(codec, true);
4391} 4391}
4392 4392
4393static void ca0132_process_dsp_response(struct hda_codec *codec) 4393static void ca0132_process_dsp_response(struct hda_codec *codec,
4394 struct hda_jack_callback *callback)
4394{ 4395{
4395 struct ca0132_spec *spec = codec->spec; 4396 struct ca0132_spec *spec = codec->spec;
4396 4397
@@ -4403,38 +4404,31 @@ static void ca0132_process_dsp_response(struct hda_codec *codec)
4403 dspio_clear_response_queue(codec); 4404 dspio_clear_response_queue(codec);
4404} 4405}
4405 4406
4406static void ca0132_unsol_event(struct hda_codec *codec, unsigned int res) 4407static void hp_callback(struct hda_codec *codec, struct hda_jack_callback *cb)
4407{ 4408{
4408 struct ca0132_spec *spec = codec->spec; 4409 struct ca0132_spec *spec = codec->spec;
4409 unsigned int tag = (res >> AC_UNSOL_RES_TAG_SHIFT) & 0x3f;
4410 4410
4411 if (tag == UNSOL_TAG_DSP) { 4411 /* Delay enabling the HP amp, to let the mic-detection
4412 ca0132_process_dsp_response(codec); 4412 * state machine run.
4413 } else { 4413 */
4414 struct hda_jack_tbl *jack; 4414 cancel_delayed_work_sync(&spec->unsol_hp_work);
4415 4415 queue_delayed_work(codec->bus->workq, &spec->unsol_hp_work,
4416 codec_dbg(codec, "snd_hda_jack_get_action: 0x%x\n", res); 4416 msecs_to_jiffies(500));
4417 jack = snd_hda_jack_tbl_get_from_tag(codec, tag); 4417 cb->tbl->block_report = 1;
4418 if (!jack) 4418}
4419 return; 4419
4420 switch (jack->nid) { 4420static void amic_callback(struct hda_codec *codec, struct hda_jack_callback *cb)
4421 case UNSOL_TAG_HP: 4421{
4422 /* Delay enabling the HP amp, to let the mic-detection 4422 ca0132_select_mic(codec);
4423 * state machine run. 4423}
4424 */ 4424
4425 cancel_delayed_work_sync(&spec->unsol_hp_work); 4425static void ca0132_init_unsol(struct hda_codec *codec)
4426 queue_delayed_work(codec->bus->workq, 4426{
4427 &spec->unsol_hp_work, 4427 snd_hda_jack_detect_enable_callback(codec, UNSOL_TAG_HP, hp_callback);
4428 msecs_to_jiffies(500)); 4428 snd_hda_jack_detect_enable_callback(codec, UNSOL_TAG_AMIC1,
4429 break; 4429 amic_callback);
4430 case UNSOL_TAG_AMIC1: 4430 snd_hda_jack_detect_enable_callback(codec, UNSOL_TAG_DSP,
4431 ca0132_select_mic(codec); 4431 ca0132_process_dsp_response);
4432 snd_hda_jack_report_sync(codec);
4433 break;
4434 default:
4435 break;
4436 }
4437 }
4438} 4432}
4439 4433
4440/* 4434/*
@@ -4445,8 +4439,6 @@ static void ca0132_unsol_event(struct hda_codec *codec, unsigned int res)
4445static struct hda_verb ca0132_base_init_verbs[] = { 4439static struct hda_verb ca0132_base_init_verbs[] = {
4446 /*enable ct extension*/ 4440 /*enable ct extension*/
4447 {0x15, VENDOR_CHIPIO_CT_EXTENSIONS_ENABLE, 0x1}, 4441 {0x15, VENDOR_CHIPIO_CT_EXTENSIONS_ENABLE, 0x1},
4448 /*enable DSP node unsol, needed for DSP download*/
4449 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | UNSOL_TAG_DSP},
4450 {} 4442 {}
4451}; 4443};
4452 4444
@@ -4563,6 +4555,8 @@ static int ca0132_init(struct hda_codec *codec)
4563 4555
4564 snd_hda_power_up(codec); 4556 snd_hda_power_up(codec);
4565 4557
4558 ca0132_init_unsol(codec);
4559
4566 ca0132_init_params(codec); 4560 ca0132_init_params(codec);
4567 ca0132_init_flags(codec); 4561 ca0132_init_flags(codec);
4568 snd_hda_sequence_write(codec, spec->base_init_verbs); 4562 snd_hda_sequence_write(codec, spec->base_init_verbs);
@@ -4585,8 +4579,6 @@ static int ca0132_init(struct hda_codec *codec)
4585 for (i = 0; i < spec->num_init_verbs; i++) 4579 for (i = 0; i < spec->num_init_verbs; i++)
4586 snd_hda_sequence_write(codec, spec->init_verbs[i]); 4580 snd_hda_sequence_write(codec, spec->init_verbs[i]);
4587 4581
4588 ca0132_init_unsol(codec);
4589
4590 ca0132_select_out(codec); 4582 ca0132_select_out(codec);
4591 ca0132_select_mic(codec); 4583 ca0132_select_mic(codec);
4592 4584
@@ -4614,7 +4606,7 @@ static struct hda_codec_ops ca0132_patch_ops = {
4614 .build_pcms = ca0132_build_pcms, 4606 .build_pcms = ca0132_build_pcms,
4615 .init = ca0132_init, 4607 .init = ca0132_init,
4616 .free = ca0132_free, 4608 .free = ca0132_free,
4617 .unsol_event = ca0132_unsol_event, 4609 .unsol_event = snd_hda_jack_unsol_event,
4618}; 4610};
4619 4611
4620static void ca0132_config(struct hda_codec *codec) 4612static void ca0132_config(struct hda_codec *codec)