Commit f8fb117034847634bff8f02632151f7535981fa1
1 parent
7c3008c47b
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
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>
Showing 1 changed file with 34 additions and 42 deletions Side-by-side Diff
sound/pci/hda/patch_ca0132.c
... | ... | @@ -3224,8 +3224,14 @@ |
3224 | 3224 | { |
3225 | 3225 | struct ca0132_spec *spec = container_of( |
3226 | 3226 | to_delayed_work(work), struct ca0132_spec, unsol_hp_work); |
3227 | + struct hda_jack_tbl *jack; | |
3228 | + | |
3227 | 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 | |
3231 | 3237 | static void ca0132_set_dmic(struct hda_codec *codec, int enable); |
... | ... | @@ -4114,12 +4120,6 @@ |
4114 | 4120 | } |
4115 | 4121 | } |
4116 | 4122 | |
4117 | -static 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 | - | |
4123 | 4123 | static void refresh_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir) |
4124 | 4124 | { |
4125 | 4125 | unsigned int caps; |
... | ... | @@ -4390,7 +4390,8 @@ |
4390 | 4390 | ca0132_set_dsp_msr(codec, true); |
4391 | 4391 | } |
4392 | 4392 | |
4393 | -static void ca0132_process_dsp_response(struct hda_codec *codec) | |
4393 | +static void ca0132_process_dsp_response(struct hda_codec *codec, | |
4394 | + struct hda_jack_callback *callback) | |
4394 | 4395 | { |
4395 | 4396 | struct ca0132_spec *spec = codec->spec; |
4396 | 4397 | |
4397 | 4398 | |
4398 | 4399 | |
4399 | 4400 | |
4400 | 4401 | |
... | ... | @@ -4403,40 +4404,33 @@ |
4403 | 4404 | dspio_clear_response_queue(codec); |
4404 | 4405 | } |
4405 | 4406 | |
4406 | -static void ca0132_unsol_event(struct hda_codec *codec, unsigned int res) | |
4407 | +static void hp_callback(struct hda_codec *codec, struct hda_jack_callback *cb) | |
4407 | 4408 | { |
4408 | 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) { | |
4412 | - ca0132_process_dsp_response(codec); | |
4413 | - } else { | |
4414 | - struct hda_jack_tbl *jack; | |
4411 | + /* Delay enabling the HP amp, to let the mic-detection | |
4412 | + * state machine run. | |
4413 | + */ | |
4414 | + cancel_delayed_work_sync(&spec->unsol_hp_work); | |
4415 | + queue_delayed_work(codec->bus->workq, &spec->unsol_hp_work, | |
4416 | + msecs_to_jiffies(500)); | |
4417 | + cb->tbl->block_report = 1; | |
4418 | +} | |
4415 | 4419 | |
4416 | - codec_dbg(codec, "snd_hda_jack_get_action: 0x%x\n", res); | |
4417 | - jack = snd_hda_jack_tbl_get_from_tag(codec, tag); | |
4418 | - if (!jack) | |
4419 | - return; | |
4420 | - switch (jack->nid) { | |
4421 | - case UNSOL_TAG_HP: | |
4422 | - /* Delay enabling the HP amp, to let the mic-detection | |
4423 | - * state machine run. | |
4424 | - */ | |
4425 | - cancel_delayed_work_sync(&spec->unsol_hp_work); | |
4426 | - queue_delayed_work(codec->bus->workq, | |
4427 | - &spec->unsol_hp_work, | |
4428 | - msecs_to_jiffies(500)); | |
4429 | - break; | |
4430 | - case UNSOL_TAG_AMIC1: | |
4431 | - ca0132_select_mic(codec); | |
4432 | - snd_hda_jack_report_sync(codec); | |
4433 | - break; | |
4434 | - default: | |
4435 | - break; | |
4436 | - } | |
4437 | - } | |
4420 | +static void amic_callback(struct hda_codec *codec, struct hda_jack_callback *cb) | |
4421 | +{ | |
4422 | + ca0132_select_mic(codec); | |
4438 | 4423 | } |
4439 | 4424 | |
4425 | +static void ca0132_init_unsol(struct hda_codec *codec) | |
4426 | +{ | |
4427 | + snd_hda_jack_detect_enable_callback(codec, UNSOL_TAG_HP, hp_callback); | |
4428 | + snd_hda_jack_detect_enable_callback(codec, UNSOL_TAG_AMIC1, | |
4429 | + amic_callback); | |
4430 | + snd_hda_jack_detect_enable_callback(codec, UNSOL_TAG_DSP, | |
4431 | + ca0132_process_dsp_response); | |
4432 | +} | |
4433 | + | |
4440 | 4434 | /* |
4441 | 4435 | * Verbs tables. |
4442 | 4436 | */ |
... | ... | @@ -4445,8 +4439,6 @@ |
4445 | 4439 | static struct hda_verb ca0132_base_init_verbs[] = { |
4446 | 4440 | /*enable ct extension*/ |
4447 | 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 @@ |
4563 | 4555 | |
4564 | 4556 | snd_hda_power_up(codec); |
4565 | 4557 | |
4558 | + ca0132_init_unsol(codec); | |
4559 | + | |
4566 | 4560 | ca0132_init_params(codec); |
4567 | 4561 | ca0132_init_flags(codec); |
4568 | 4562 | snd_hda_sequence_write(codec, spec->base_init_verbs); |
... | ... | @@ -4585,8 +4579,6 @@ |
4585 | 4579 | for (i = 0; i < spec->num_init_verbs; i++) |
4586 | 4580 | snd_hda_sequence_write(codec, spec->init_verbs[i]); |
4587 | 4581 | |
4588 | - ca0132_init_unsol(codec); | |
4589 | - | |
4590 | 4582 | ca0132_select_out(codec); |
4591 | 4583 | ca0132_select_mic(codec); |
4592 | 4584 | |
... | ... | @@ -4614,7 +4606,7 @@ |
4614 | 4606 | .build_pcms = ca0132_build_pcms, |
4615 | 4607 | .init = ca0132_init, |
4616 | 4608 | .free = ca0132_free, |
4617 | - .unsol_event = ca0132_unsol_event, | |
4609 | + .unsol_event = snd_hda_jack_unsol_event, | |
4618 | 4610 | }; |
4619 | 4611 | |
4620 | 4612 | static void ca0132_config(struct hda_codec *codec) |