From 1835a0f9a2121ce3198dab67507d4d3e960cc09e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 27 Oct 2011 22:12:46 +0200 Subject: ALSA: hda - Cache the jack-detection value Introduce a table containing the pins and their jack-detection states for avoiding the unnecessary verbs to check the pin status at each time. When the unsol event is enabled via snd_hda_jack_detect_enable(), it automatically adds the given NID to the table. Then the driver supposes that the codec driver will set the dirty flag appropariately when an unsolicited event is invoked for that pin. The behavior for reading other pins that aren't registered in the table doesn't change. Only the pins assigned to the table are cached, so far. In near futre, this table can be extended to use the central place for the unsolicited events of all pins, etc, and eventually include the jack-detect kcontrols that replace the current input-jack stuff. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'sound/pci/hda/patch_realtek.c') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 14feecf2d80..da9d2276e68 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -33,6 +33,7 @@ #include "hda_codec.h" #include "hda_local.h" #include "hda_beep.h" +#include "hda_jack.h" /* unsol event tags */ #define ALC_FRONT_EVENT 0x01 @@ -664,6 +665,7 @@ static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) res >>= 28; else res >>= 26; + snd_hda_jack_set_dirty_all(codec); /* FIXME: to be more fine-grained */ switch (res) { case ALC_HP_EVENT: alc_hp_automute(codec); @@ -964,9 +966,7 @@ static void alc_init_automute(struct hda_codec *codec) continue; snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n", nid); - snd_hda_codec_write_cache(codec, nid, 0, - AC_VERB_SET_UNSOLICITED_ENABLE, - AC_USRSP_EN | ALC_HP_EVENT); + snd_hda_jack_detect_enable(codec, nid, ALC_HP_EVENT); spec->detect_hp = 1; } @@ -978,9 +978,8 @@ static void alc_init_automute(struct hda_codec *codec) continue; snd_printdd("realtek: Enable Line-Out " "auto-muting on NID 0x%x\n", nid); - snd_hda_codec_write_cache(codec, nid, 0, - AC_VERB_SET_UNSOLICITED_ENABLE, - AC_USRSP_EN | ALC_FRONT_EVENT); + snd_hda_jack_detect_enable(codec, nid, + ALC_FRONT_EVENT); spec->detect_lo = 1; } spec->automute_lo_possible = spec->detect_hp; @@ -1108,13 +1107,10 @@ static bool alc_auto_mic_check_imux(struct hda_codec *codec) return false; /* no corresponding imux */ } - snd_hda_codec_write_cache(codec, spec->ext_mic_pin, 0, - AC_VERB_SET_UNSOLICITED_ENABLE, - AC_USRSP_EN | ALC_MIC_EVENT); + snd_hda_jack_detect_enable(codec, spec->ext_mic_pin, ALC_MIC_EVENT); if (spec->dock_mic_pin) - snd_hda_codec_write_cache(codec, spec->dock_mic_pin, 0, - AC_VERB_SET_UNSOLICITED_ENABLE, - AC_USRSP_EN | ALC_MIC_EVENT); + snd_hda_jack_detect_enable(codec, spec->dock_mic_pin, + ALC_MIC_EVENT); spec->auto_mic_valid_imux = 1; spec->auto_mic = 1; -- cgit v1.2.3 From 01a61e12b4602c82bde9797d0e153f3e53c95b04 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 28 Oct 2011 00:03:22 +0200 Subject: ALSA: hda - Create jack-detection kcontrols Create kcontrols for pin jack-detections, which work similarly like jack-input layer. Each control will notify when the jack is plugged or unplugged, and also user can read the value at any time via the normal control API. The control elements are created with iface=CARD, so that they won't appear in the mixer apps. So far, only the pins that enabled the jack-detection are registered. For covering all pins, the transition of the common unsol-tag handling would be needed. Stay tuned. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'sound/pci/hda/patch_realtek.c') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index da9d2276e68..04beae034fe 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -677,6 +677,7 @@ static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) alc_mic_automute(codec); break; } + snd_hda_jack_report_sync(codec); } /* call init functions of standard auto-mute helpers */ @@ -2054,6 +2055,10 @@ static int alc_build_controls(struct hda_codec *codec) alc_free_kctls(codec); /* no longer needed */ + err = snd_hda_jack_add_kctls(codec, &spec->autocfg); + if (err < 0) + return err; + return 0; } @@ -2081,6 +2086,8 @@ static int alc_init(struct hda_codec *codec) alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT); + snd_hda_jack_report_sync(codec); + hda_call_check_power_status(codec, 0x01); return 0; } -- cgit v1.2.3 From 3a93897ea37cbb8277f8a4232c12c0c18168a7db Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 28 Oct 2011 01:16:55 +0200 Subject: ALSA: hda - Manage unsol tags in hda_jack.c Manage the tags assigned for unsolicited events dynamically together with the jack-detection routines. Basically this is almost same as what we've done in patch_sigmatel.c. Assign the new tag number for each new unsol event, associate with the given NID and the action type, etc. With this change, now all pins looked over in snd_hda_jack_add_kctls() are actually enabled for detection now even if the pins aren't used for jack-retasking by the driver. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'sound/pci/hda/patch_realtek.c') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 04beae034fe..9a90cdac78f 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -185,6 +185,7 @@ struct alc_spec { unsigned int vol_in_capsrc:1; /* use capsrc volume (ADC has no vol) */ unsigned int parse_flags; /* passed to snd_hda_parse_pin_defcfg() */ unsigned int shared_mic_hp:1; /* HP/Mic-in sharing */ + unsigned int use_jack_tbl:1; /* 1 for model=auto */ /* auto-mute control */ int automute_mode; @@ -661,11 +662,13 @@ static void alc_mic_automute(struct hda_codec *codec) /* unsolicited event for HP jack sensing */ static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) { + struct alc_spec *spec = codec->spec; if (codec->vendor_id == 0x10ec0880) res >>= 28; else res >>= 26; - snd_hda_jack_set_dirty_all(codec); /* FIXME: to be more fine-grained */ + if (spec->use_jack_tbl) + res = snd_hda_jack_get_action(codec, res); switch (res) { case ALC_HP_EVENT: alc_hp_automute(codec); @@ -3896,6 +3899,7 @@ static void set_capture_mixer(struct hda_codec *codec) static void alc_auto_init_std(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; + spec->use_jack_tbl = 1; alc_auto_init_multi_out(codec); alc_auto_init_extra_out(codec); alc_auto_init_analog_input(codec); -- cgit v1.2.3 From aad37dbd563010252e1bedb6dad6cddb867b9235 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 2 Nov 2011 08:54:51 +0100 Subject: ALSA: hda - Merge input-jack helpers to hda_jack.c We can use the very same table in hda_jack.c for managing the list for input-jack elements, too. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 1 - 1 file changed, 1 deletion(-) (limited to 'sound/pci/hda/patch_realtek.c') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 9a90cdac78f..933c8cf23b2 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -2474,7 +2474,6 @@ static void alc_free(struct hda_codec *codec) return; alc_shutup(codec); - snd_hda_input_jack_free(codec); alc_free_kctls(codec); alc_free_bind_ctls(codec); kfree(spec); -- cgit v1.2.3 From 31ef22579302ac42054bebecb528710f46580925 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 1 Dec 2011 17:41:36 +0100 Subject: ALSA: hda - Integrate input-jack stuff into kctl-jack Instead of managing input-jack stuff separately, call all stuff inside the kctl-jack creation, deletion and report. The caller no longer needs to care about input-jack. The better integration between input-jack and kctl-jack should be done in the upper layer in near future, but for now, it's implemented locally for more tests. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 52 ------------------------------------------- 1 file changed, 52 deletions(-) (limited to 'sound/pci/hda/patch_realtek.c') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 933c8cf23b2..641c8295b64 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -460,46 +460,6 @@ static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid, alc_fix_pll(codec); } -/* - * Jack-reporting via input-jack layer - */ - -/* initialization of jacks; currently checks only a few known pins */ -static int alc_init_jacks(struct hda_codec *codec) -{ -#ifdef CONFIG_SND_HDA_INPUT_JACK - struct alc_spec *spec = codec->spec; - int err; - unsigned int hp_nid = spec->autocfg.hp_pins[0]; - unsigned int mic_nid = spec->ext_mic_pin; - unsigned int dock_nid = spec->dock_mic_pin; - - if (hp_nid) { - err = snd_hda_input_jack_add(codec, hp_nid, - SND_JACK_HEADPHONE, NULL); - if (err < 0) - return err; - snd_hda_input_jack_report(codec, hp_nid); - } - - if (mic_nid) { - err = snd_hda_input_jack_add(codec, mic_nid, - SND_JACK_MICROPHONE, NULL); - if (err < 0) - return err; - snd_hda_input_jack_report(codec, mic_nid); - } - if (dock_nid) { - err = snd_hda_input_jack_add(codec, dock_nid, - SND_JACK_MICROPHONE, NULL); - if (err < 0) - return err; - snd_hda_input_jack_report(codec, dock_nid); - } -#endif /* CONFIG_SND_HDA_INPUT_JACK */ - return 0; -} - /* * Jack detections for HP auto-mute and mic-switch */ @@ -513,7 +473,6 @@ static bool detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins) hda_nid_t nid = pins[i]; if (!nid) break; - snd_hda_input_jack_report(codec, nid); present |= snd_hda_jack_detect(codec, nid); } return present; @@ -653,10 +612,6 @@ static void alc_mic_automute(struct hda_codec *codec) alc_mux_select(codec, 0, spec->dock_mic_idx, false); else alc_mux_select(codec, 0, spec->int_mic_idx, false); - - snd_hda_input_jack_report(codec, pins[spec->ext_mic_idx]); - if (spec->dock_mic_idx >= 0) - snd_hda_input_jack_report(codec, pins[spec->dock_mic_idx]); } /* unsolicited event for HP jack sensing */ @@ -4686,7 +4641,6 @@ static int patch_alc882(struct hda_codec *codec) if (board_config == ALC_MODEL_AUTO) spec->init_hook = alc_auto_init_std; - alc_init_jacks(codec); #ifdef CONFIG_SND_HDA_POWER_SAVE if (!spec->loopback.amplist) spec->loopback.amplist = alc882_loopbacks; @@ -4866,7 +4820,6 @@ static int patch_alc262(struct hda_codec *codec) spec->init_hook = alc_auto_init_std; spec->shutup = alc_eapd_shutup; - alc_init_jacks(codec); #ifdef CONFIG_SND_HDA_POWER_SAVE if (!spec->loopback.amplist) spec->loopback.amplist = alc262_loopbacks; @@ -4979,8 +4932,6 @@ static int patch_alc268(struct hda_codec *codec) spec->init_hook = alc_auto_init_std; spec->shutup = alc_eapd_shutup; - alc_init_jacks(codec); - return 0; error: @@ -5538,7 +5489,6 @@ static int patch_alc269(struct hda_codec *codec) spec->init_hook = alc_auto_init_std; spec->shutup = alc269_shutup; - alc_init_jacks(codec); #ifdef CONFIG_SND_HDA_POWER_SAVE if (!spec->loopback.amplist) spec->loopback.amplist = alc269_loopbacks; @@ -6153,8 +6103,6 @@ static int patch_alc662(struct hda_codec *codec) spec->init_hook = alc_auto_init_std; spec->shutup = alc_eapd_shutup; - alc_init_jacks(codec); - #ifdef CONFIG_SND_HDA_POWER_SAVE if (!spec->loopback.amplist) spec->loopback.amplist = alc662_loopbacks; -- cgit v1.2.3