aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda')
-rw-r--r--sound/pci/hda/Makefile2
-rw-r--r--sound/pci/hda/hda_codec.c40
-rw-r--r--sound/pci/hda/hda_codec.h3
-rw-r--r--sound/pci/hda/hda_jack.c148
-rw-r--r--sound/pci/hda/hda_jack.h63
-rw-r--r--sound/pci/hda/hda_local.h15
-rw-r--r--sound/pci/hda/patch_analog.c1
-rw-r--r--sound/pci/hda/patch_cirrus.c18
-rw-r--r--sound/pci/hda/patch_conexant.c20
-rw-r--r--sound/pci/hda/patch_hdmi.c6
-rw-r--r--sound/pci/hda/patch_realtek.c20
-rw-r--r--sound/pci/hda/patch_sigmatel.c46
-rw-r--r--sound/pci/hda/patch_via.c19
13 files changed, 284 insertions, 117 deletions
diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile
index f928d6634723..ace157cc3d15 100644
--- a/sound/pci/hda/Makefile
+++ b/sound/pci/hda/Makefile
@@ -1,6 +1,6 @@
1snd-hda-intel-objs := hda_intel.o 1snd-hda-intel-objs := hda_intel.o
2 2
3snd-hda-codec-y := hda_codec.o 3snd-hda-codec-y := hda_codec.o hda_jack.o
4snd-hda-codec-$(CONFIG_SND_HDA_GENERIC) += hda_generic.o 4snd-hda-codec-$(CONFIG_SND_HDA_GENERIC) += hda_generic.o
5snd-hda-codec-$(CONFIG_PROC_FS) += hda_proc.o 5snd-hda-codec-$(CONFIG_PROC_FS) += hda_proc.o
6snd-hda-codec-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o 6snd-hda-codec-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index c6ff9b9de553..8217ff7ff7b5 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -33,6 +33,7 @@
33#include <sound/jack.h> 33#include <sound/jack.h>
34#include "hda_local.h" 34#include "hda_local.h"
35#include "hda_beep.h" 35#include "hda_beep.h"
36#include "hda_jack.h"
36#include <sound/hda_hwdep.h> 37#include <sound/hda_hwdep.h>
37 38
38#define CREATE_TRACE_POINTS 39#define CREATE_TRACE_POINTS
@@ -1723,43 +1724,6 @@ int snd_hda_override_pin_caps(struct hda_codec *codec, hda_nid_t nid,
1723} 1724}
1724EXPORT_SYMBOL_HDA(snd_hda_override_pin_caps); 1725EXPORT_SYMBOL_HDA(snd_hda_override_pin_caps);
1725 1726
1726/**
1727 * snd_hda_pin_sense - execute pin sense measurement
1728 * @codec: the CODEC to sense
1729 * @nid: the pin NID to sense
1730 *
1731 * Execute necessary pin sense measurement and return its Presence Detect,
1732 * Impedance, ELD Valid etc. status bits.
1733 */
1734u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid)
1735{
1736 u32 pincap;
1737
1738 if (!codec->no_trigger_sense) {
1739 pincap = snd_hda_query_pin_caps(codec, nid);
1740 if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */
1741 snd_hda_codec_read(codec, nid, 0,
1742 AC_VERB_SET_PIN_SENSE, 0);
1743 }
1744 return snd_hda_codec_read(codec, nid, 0,
1745 AC_VERB_GET_PIN_SENSE, 0);
1746}
1747EXPORT_SYMBOL_HDA(snd_hda_pin_sense);
1748
1749/**
1750 * snd_hda_jack_detect - query pin Presence Detect status
1751 * @codec: the CODEC to sense
1752 * @nid: the pin NID to sense
1753 *
1754 * Query and return the pin's Presence Detect status.
1755 */
1756int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid)
1757{
1758 u32 sense = snd_hda_pin_sense(codec, nid);
1759 return !!(sense & AC_PINSENSE_PRESENCE);
1760}
1761EXPORT_SYMBOL_HDA(snd_hda_jack_detect);
1762
1763/* 1727/*
1764 * read the current volume to info 1728 * read the current volume to info
1765 * if the cache exists, read the cache value. 1729 * if the cache exists, read the cache value.
@@ -2308,6 +2272,7 @@ int snd_hda_codec_reset(struct hda_codec *codec)
2308 } 2272 }
2309 if (codec->patch_ops.free) 2273 if (codec->patch_ops.free)
2310 codec->patch_ops.free(codec); 2274 codec->patch_ops.free(codec);
2275 snd_hda_jack_tbl_clear(codec);
2311 codec->proc_widget_hook = NULL; 2276 codec->proc_widget_hook = NULL;
2312 codec->spec = NULL; 2277 codec->spec = NULL;
2313 free_hda_cache(&codec->amp_cache); 2278 free_hda_cache(&codec->amp_cache);
@@ -3364,6 +3329,7 @@ static void hda_call_codec_resume(struct hda_codec *codec)
3364 restore_pincfgs(codec); /* restore all current pin configs */ 3329 restore_pincfgs(codec); /* restore all current pin configs */
3365 restore_shutup_pins(codec); 3330 restore_shutup_pins(codec);
3366 hda_exec_init_verbs(codec); 3331 hda_exec_init_verbs(codec);
3332 snd_hda_jack_set_dirty_all(codec);
3367 if (codec->patch_ops.resume) 3333 if (codec->patch_ops.resume)
3368 codec->patch_ops.resume(codec); 3334 codec->patch_ops.resume(codec);
3369 else { 3335 else {
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 564471169cae..97aa65d1f1d1 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -869,6 +869,9 @@ struct hda_codec {
869 void (*proc_widget_hook)(struct snd_info_buffer *buffer, 869 void (*proc_widget_hook)(struct snd_info_buffer *buffer,
870 struct hda_codec *codec, hda_nid_t nid); 870 struct hda_codec *codec, hda_nid_t nid);
871 871
872 /* jack detection */
873 struct snd_array jacktbl;
874
872#ifdef CONFIG_SND_HDA_INPUT_JACK 875#ifdef CONFIG_SND_HDA_INPUT_JACK
873 /* jack detection */ 876 /* jack detection */
874 struct snd_array jacks; 877 struct snd_array jacks;
diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c
new file mode 100644
index 000000000000..64b78a2e20e0
--- /dev/null
+++ b/sound/pci/hda/hda_jack.c
@@ -0,0 +1,148 @@
1/*
2 * Jack-detection handling for HD-audio
3 *
4 * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
5 *
6 * This driver is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11
12#include <linux/init.h>
13#include <linux/slab.h>
14#include <sound/core.h>
15#include "hda_codec.h"
16#include "hda_local.h"
17#include "hda_jack.h"
18
19/* execute pin sense measurement */
20static u32 read_pin_sense(struct hda_codec *codec, hda_nid_t nid)
21{
22 u32 pincap;
23
24 if (!codec->no_trigger_sense) {
25 pincap = snd_hda_query_pin_caps(codec, nid);
26 if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */
27 snd_hda_codec_read(codec, nid, 0,
28 AC_VERB_SET_PIN_SENSE, 0);
29 }
30 return snd_hda_codec_read(codec, nid, 0,
31 AC_VERB_GET_PIN_SENSE, 0);
32}
33
34/**
35 * snd_hda_jack_tbl_get - query the jack-table entry for the given NID
36 */
37struct hda_jack_tbl *
38snd_hda_jack_tbl_get(struct hda_codec *codec, hda_nid_t nid)
39{
40 struct hda_jack_tbl *jack = codec->jacktbl.list;
41 int i;
42
43 if (!nid || !jack)
44 return NULL;
45 for (i = 0; i < codec->jacktbl.used; i++, jack++)
46 if (jack->nid == nid)
47 return jack;
48 return NULL;
49}
50EXPORT_SYMBOL_HDA(snd_hda_jack_tbl_get);
51
52/**
53 * snd_hda_jack_tbl_new - create a jack-table entry for the given NID
54 */
55struct hda_jack_tbl *
56snd_hda_jack_tbl_new(struct hda_codec *codec, hda_nid_t nid)
57{
58 struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid);
59 if (jack)
60 return jack;
61 snd_array_init(&codec->jacktbl, sizeof(*jack), 16);
62 jack = snd_array_new(&codec->jacktbl);
63 if (!jack)
64 return NULL;
65 jack->nid = nid;
66 jack->jack_dirty = 1;
67 return jack;
68}
69
70void snd_hda_jack_tbl_clear(struct hda_codec *codec)
71{
72 snd_array_free(&codec->jacktbl);
73}
74
75/* update the cached value and notification flag if needed */
76static void jack_detect_update(struct hda_codec *codec,
77 struct hda_jack_tbl *jack)
78{
79 if (jack->jack_dirty) {
80 jack->pin_sense = read_pin_sense(codec, jack->nid);
81 jack->jack_dirty = 0;
82 }
83}
84
85/**
86 * snd_hda_set_dirty_all - Mark all the cached as dirty
87 *
88 * This function sets the dirty flag to all entries of jack table.
89 * It's called from the resume path in hda_codec.c.
90 */
91void snd_hda_jack_set_dirty_all(struct hda_codec *codec)
92{
93 struct hda_jack_tbl *jack = codec->jacktbl.list;
94 int i;
95
96 for (i = 0; i < codec->jacktbl.used; i++, jack++)
97 if (jack->nid)
98 jack->jack_dirty = 1;
99}
100EXPORT_SYMBOL_HDA(snd_hda_jack_set_dirty_all);
101
102/**
103 * snd_hda_pin_sense - execute pin sense measurement
104 * @codec: the CODEC to sense
105 * @nid: the pin NID to sense
106 *
107 * Execute necessary pin sense measurement and return its Presence Detect,
108 * Impedance, ELD Valid etc. status bits.
109 */
110u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid)
111{
112 struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid);
113 if (jack) {
114 jack_detect_update(codec, jack);
115 return jack->pin_sense;
116 }
117 return read_pin_sense(codec, nid);
118}
119EXPORT_SYMBOL_HDA(snd_hda_pin_sense);
120
121/**
122 * snd_hda_jack_detect - query pin Presence Detect status
123 * @codec: the CODEC to sense
124 * @nid: the pin NID to sense
125 *
126 * Query and return the pin's Presence Detect status.
127 */
128int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid)
129{
130 u32 sense = snd_hda_pin_sense(codec, nid);
131 return !!(sense & AC_PINSENSE_PRESENCE);
132}
133EXPORT_SYMBOL_HDA(snd_hda_jack_detect);
134
135/**
136 * snd_hda_jack_detect_enable - enable the jack-detection
137 */
138int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid,
139 unsigned int tag)
140{
141 struct hda_jack_tbl *jack = snd_hda_jack_tbl_new(codec, nid);
142 if (!jack)
143 return -ENOMEM;
144 return snd_hda_codec_write_cache(codec, nid, 0,
145 AC_VERB_SET_UNSOLICITED_ENABLE,
146 AC_USRSP_EN | tag);
147}
148EXPORT_SYMBOL_HDA(snd_hda_jack_detect_enable);
diff --git a/sound/pci/hda/hda_jack.h b/sound/pci/hda/hda_jack.h
new file mode 100644
index 000000000000..5c1bcb8cf565
--- /dev/null
+++ b/sound/pci/hda/hda_jack.h
@@ -0,0 +1,63 @@
1/*
2 * Jack-detection handling for HD-audio
3 *
4 * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
5 *
6 * This driver is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11
12#ifndef __SOUND_HDA_JACK_H
13#define __SOUND_HDA_JACK_H
14
15struct hda_jack_tbl {
16 hda_nid_t nid;
17 unsigned int pin_sense; /* cached pin-sense value */
18 unsigned int jack_dirty:1; /* needs to update? */
19};
20
21struct hda_jack_tbl *
22snd_hda_jack_tbl_get(struct hda_codec *codec, hda_nid_t nid);
23
24struct hda_jack_tbl *
25snd_hda_jack_tbl_new(struct hda_codec *codec, hda_nid_t nid);
26void snd_hda_jack_tbl_clear(struct hda_codec *codec);
27
28/**
29 * snd_hda_jack_set_dirty - set the dirty flag for the given jack-entry
30 *
31 * Call this function when a pin-state may change, e.g. when the hardware
32 * notifies via an unsolicited event.
33 */
34static inline void snd_hda_jack_set_dirty(struct hda_codec *codec,
35 hda_nid_t nid)
36{
37 struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid);
38 if (jack)
39 jack->jack_dirty = 1;
40}
41
42void snd_hda_jack_set_dirty_all(struct hda_codec *codec);
43
44int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid,
45 unsigned int tag);
46
47u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid);
48int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid);
49
50static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid)
51{
52 if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT))
53 return false;
54 if (!codec->ignore_misc_bit &&
55 (get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) &
56 AC_DEFCFG_MISC_NO_PRESENCE))
57 return false;
58 if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP))
59 return false;
60 return true;
61}
62
63#endif /* __SOUND_HDA_JACK_H */
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 7a10fe95211e..08e88b826d27 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -505,21 +505,6 @@ int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
505u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid); 505u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid);
506int snd_hda_override_pin_caps(struct hda_codec *codec, hda_nid_t nid, 506int snd_hda_override_pin_caps(struct hda_codec *codec, hda_nid_t nid,
507 unsigned int caps); 507 unsigned int caps);
508u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid);
509int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid);
510
511static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid)
512{
513 if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT))
514 return false;
515 if (!codec->ignore_misc_bit &&
516 (get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) &
517 AC_DEFCFG_MISC_NO_PRESENCE))
518 return false;
519 if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP))
520 return false;
521 return true;
522}
523 508
524/* flags for hda_nid_item */ 509/* flags for hda_nid_item */
525#define HDA_NID_ITEM_AMP (1<<0) 510#define HDA_NID_ITEM_AMP (1<<0)
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index bcb3310c394f..9cb14b42dfff 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -29,6 +29,7 @@
29#include "hda_codec.h" 29#include "hda_codec.h"
30#include "hda_local.h" 30#include "hda_local.h"
31#include "hda_beep.h" 31#include "hda_beep.h"
32#include "hda_jack.h"
32 33
33struct ad198x_spec { 34struct ad198x_spec {
34 const struct snd_kcontrol_new *mixers[6]; 35 const struct snd_kcontrol_new *mixers[6];
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index 34a460bd27bb..6f158777f71a 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -26,6 +26,7 @@
26#include <sound/core.h> 26#include <sound/core.h>
27#include "hda_codec.h" 27#include "hda_codec.h"
28#include "hda_local.h" 28#include "hda_local.h"
29#include "hda_jack.h"
29#include <sound/tlv.h> 30#include <sound/tlv.h>
30 31
31/* 32/*
@@ -1020,9 +1021,7 @@ static void init_output(struct hda_codec *codec)
1020 if (!cfg->speaker_outs) 1021 if (!cfg->speaker_outs)
1021 continue; 1022 continue;
1022 if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) { 1023 if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) {
1023 snd_hda_codec_write(codec, nid, 0, 1024 snd_hda_jack_detect_enable(codec, nid, HP_EVENT);
1024 AC_VERB_SET_UNSOLICITED_ENABLE,
1025 AC_USRSP_EN | HP_EVENT);
1026 spec->hp_detect = 1; 1025 spec->hp_detect = 1;
1027 } 1026 }
1028 } 1027 }
@@ -1063,9 +1062,7 @@ static void init_input(struct hda_codec *codec)
1063 AC_VERB_SET_AMP_GAIN_MUTE, 1062 AC_VERB_SET_AMP_GAIN_MUTE,
1064 AMP_IN_MUTE(spec->adc_idx[i])); 1063 AMP_IN_MUTE(spec->adc_idx[i]));
1065 if (spec->mic_detect && spec->automic_idx == i) 1064 if (spec->mic_detect && spec->automic_idx == i)
1066 snd_hda_codec_write(codec, pin, 0, 1065 snd_hda_jack_detect_enable(codec, pin, MIC_EVENT);
1067 AC_VERB_SET_UNSOLICITED_ENABLE,
1068 AC_USRSP_EN | MIC_EVENT);
1069 } 1066 }
1070 /* specific to CS421x */ 1067 /* specific to CS421x */
1071 if (spec->vendor_nid == CS421X_VENDOR_NID) { 1068 if (spec->vendor_nid == CS421X_VENDOR_NID) {
@@ -1227,6 +1224,8 @@ static void cs_free(struct hda_codec *codec)
1227 1224
1228static void cs_unsol_event(struct hda_codec *codec, unsigned int res) 1225static void cs_unsol_event(struct hda_codec *codec, unsigned int res)
1229{ 1226{
1227 snd_hda_jack_set_dirty_all(codec); /* FIXME: to be more fine-grained */
1228
1230 switch ((res >> 26) & 0x7f) { 1229 switch ((res >> 26) & 0x7f) {
1231 case HP_EVENT: 1230 case HP_EVENT:
1232 cs_automute(codec); 1231 cs_automute(codec);
@@ -1585,10 +1584,7 @@ static void init_cs421x_digital(struct hda_codec *codec)
1585 if (!cfg->speaker_outs) 1584 if (!cfg->speaker_outs)
1586 continue; 1585 continue;
1587 if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) { 1586 if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) {
1588 1587 snd_hda_jack_detect_enable(codec, nid, SPDIF_EVENT);
1589 snd_hda_codec_write(codec, nid, 0,
1590 AC_VERB_SET_UNSOLICITED_ENABLE,
1591 AC_USRSP_EN | SPDIF_EVENT);
1592 spec->spdif_detect = 1; 1588 spec->spdif_detect = 1;
1593 } 1589 }
1594 } 1590 }
@@ -1806,6 +1802,8 @@ static int cs421x_build_controls(struct hda_codec *codec)
1806 1802
1807static void cs421x_unsol_event(struct hda_codec *codec, unsigned int res) 1803static void cs421x_unsol_event(struct hda_codec *codec, unsigned int res)
1808{ 1804{
1805 snd_hda_jack_set_dirty_all(codec); /* FIXME: to be more fine-grained */
1806
1809 switch ((res >> 26) & 0x3f) { 1807 switch ((res >> 26) & 0x3f) {
1810 case HP_EVENT: 1808 case HP_EVENT:
1811 case SPDIF_EVENT: 1809 case SPDIF_EVENT:
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 0de21193a2b0..220e567ccfff 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -31,6 +31,7 @@
31#include "hda_codec.h" 31#include "hda_codec.h"
32#include "hda_local.h" 32#include "hda_local.h"
33#include "hda_beep.h" 33#include "hda_beep.h"
34#include "hda_jack.h"
34 35
35#define CXT_PIN_DIR_IN 0x00 36#define CXT_PIN_DIR_IN 0x00
36#define CXT_PIN_DIR_OUT 0x01 37#define CXT_PIN_DIR_OUT 0x01
@@ -3756,6 +3757,7 @@ static void cx_auto_automic(struct hda_codec *codec)
3756static void cx_auto_unsol_event(struct hda_codec *codec, unsigned int res) 3757static void cx_auto_unsol_event(struct hda_codec *codec, unsigned int res)
3757{ 3758{
3758 int nid = (res & AC_UNSOL_RES_SUBTAG) >> 20; 3759 int nid = (res & AC_UNSOL_RES_SUBTAG) >> 20;
3760 snd_hda_jack_set_dirty(codec, nid);
3759 switch (res >> 26) { 3761 switch (res >> 26) {
3760 case CONEXANT_HP_EVENT: 3762 case CONEXANT_HP_EVENT:
3761 cx_auto_hp_automute(codec); 3763 cx_auto_hp_automute(codec);
@@ -3983,9 +3985,7 @@ static void enable_unsol_pins(struct hda_codec *codec, int num_pins,
3983{ 3985{
3984 int i; 3986 int i;
3985 for (i = 0; i < num_pins; i++) 3987 for (i = 0; i < num_pins; i++)
3986 snd_hda_codec_write(codec, pins[i], 0, 3988 snd_hda_jack_detect_enable(codec, pins[i], tag);
3987 AC_VERB_SET_UNSOLICITED_ENABLE,
3988 AC_USRSP_EN | tag);
3989} 3989}
3990 3990
3991static void cx_auto_init_output(struct hda_codec *codec) 3991static void cx_auto_init_output(struct hda_codec *codec)
@@ -4060,16 +4060,14 @@ static void cx_auto_init_input(struct hda_codec *codec)
4060 4060
4061 if (spec->auto_mic) { 4061 if (spec->auto_mic) {
4062 if (spec->auto_mic_ext >= 0) { 4062 if (spec->auto_mic_ext >= 0) {
4063 snd_hda_codec_write(codec, 4063 snd_hda_jack_detect_enable(codec,
4064 cfg->inputs[spec->auto_mic_ext].pin, 0, 4064 cfg->inputs[spec->auto_mic_ext].pin,
4065 AC_VERB_SET_UNSOLICITED_ENABLE, 4065 CONEXANT_MIC_EVENT);
4066 AC_USRSP_EN | CONEXANT_MIC_EVENT);
4067 } 4066 }
4068 if (spec->auto_mic_dock >= 0) { 4067 if (spec->auto_mic_dock >= 0) {
4069 snd_hda_codec_write(codec, 4068 snd_hda_jack_detect_enable(codec,
4070 cfg->inputs[spec->auto_mic_dock].pin, 0, 4069 cfg->inputs[spec->auto_mic_dock].pin,
4071 AC_VERB_SET_UNSOLICITED_ENABLE, 4070 CONEXANT_MIC_EVENT);
4072 AC_USRSP_EN | CONEXANT_MIC_EVENT);
4073 } 4071 }
4074 cx_auto_automic(codec); 4072 cx_auto_automic(codec);
4075 } else { 4073 } else {
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 9850c5b481ea..ea6d85d48444 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -36,6 +36,7 @@
36#include <sound/jack.h> 36#include <sound/jack.h>
37#include "hda_codec.h" 37#include "hda_codec.h"
38#include "hda_local.h" 38#include "hda_local.h"
39#include "hda_jack.h"
39 40
40static bool static_hdmi_pcm; 41static bool static_hdmi_pcm;
41module_param(static_hdmi_pcm, bool, 0644); 42module_param(static_hdmi_pcm, bool, 0644);
@@ -766,6 +767,7 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
766 if (pin_idx < 0) 767 if (pin_idx < 0)
767 return; 768 return;
768 769
770 snd_hda_jack_set_dirty(codec, pin_nid);
769 hdmi_present_sense(&spec->pins[pin_idx], true); 771 hdmi_present_sense(&spec->pins[pin_idx], true);
770} 772}
771 773
@@ -1282,9 +1284,7 @@ static int generic_hdmi_init(struct hda_codec *codec)
1282 struct hdmi_eld *eld = &per_pin->sink_eld; 1284 struct hdmi_eld *eld = &per_pin->sink_eld;
1283 1285
1284 hdmi_init_pin(codec, pin_nid); 1286 hdmi_init_pin(codec, pin_nid);
1285 snd_hda_codec_write(codec, pin_nid, 0, 1287 snd_hda_jack_detect_enable(codec, pin_nid, pin_nid);
1286 AC_VERB_SET_UNSOLICITED_ENABLE,
1287 AC_USRSP_EN | pin_nid);
1288 1288
1289 per_pin->codec = codec; 1289 per_pin->codec = codec;
1290 INIT_DELAYED_WORK(&per_pin->work, hdmi_repoll_eld); 1290 INIT_DELAYED_WORK(&per_pin->work, hdmi_repoll_eld);
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 14feecf2d802..da9d2276e68b 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -33,6 +33,7 @@
33#include "hda_codec.h" 33#include "hda_codec.h"
34#include "hda_local.h" 34#include "hda_local.h"
35#include "hda_beep.h" 35#include "hda_beep.h"
36#include "hda_jack.h"
36 37
37/* unsol event tags */ 38/* unsol event tags */
38#define ALC_FRONT_EVENT 0x01 39#define ALC_FRONT_EVENT 0x01
@@ -664,6 +665,7 @@ static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
664 res >>= 28; 665 res >>= 28;
665 else 666 else
666 res >>= 26; 667 res >>= 26;
668 snd_hda_jack_set_dirty_all(codec); /* FIXME: to be more fine-grained */
667 switch (res) { 669 switch (res) {
668 case ALC_HP_EVENT: 670 case ALC_HP_EVENT:
669 alc_hp_automute(codec); 671 alc_hp_automute(codec);
@@ -964,9 +966,7 @@ static void alc_init_automute(struct hda_codec *codec)
964 continue; 966 continue;
965 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n", 967 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
966 nid); 968 nid);
967 snd_hda_codec_write_cache(codec, nid, 0, 969 snd_hda_jack_detect_enable(codec, nid, ALC_HP_EVENT);
968 AC_VERB_SET_UNSOLICITED_ENABLE,
969 AC_USRSP_EN | ALC_HP_EVENT);
970 spec->detect_hp = 1; 970 spec->detect_hp = 1;
971 } 971 }
972 972
@@ -978,9 +978,8 @@ static void alc_init_automute(struct hda_codec *codec)
978 continue; 978 continue;
979 snd_printdd("realtek: Enable Line-Out " 979 snd_printdd("realtek: Enable Line-Out "
980 "auto-muting on NID 0x%x\n", nid); 980 "auto-muting on NID 0x%x\n", nid);
981 snd_hda_codec_write_cache(codec, nid, 0, 981 snd_hda_jack_detect_enable(codec, nid,
982 AC_VERB_SET_UNSOLICITED_ENABLE, 982 ALC_FRONT_EVENT);
983 AC_USRSP_EN | ALC_FRONT_EVENT);
984 spec->detect_lo = 1; 983 spec->detect_lo = 1;
985 } 984 }
986 spec->automute_lo_possible = spec->detect_hp; 985 spec->automute_lo_possible = spec->detect_hp;
@@ -1108,13 +1107,10 @@ static bool alc_auto_mic_check_imux(struct hda_codec *codec)
1108 return false; /* no corresponding imux */ 1107 return false; /* no corresponding imux */
1109 } 1108 }
1110 1109
1111 snd_hda_codec_write_cache(codec, spec->ext_mic_pin, 0, 1110 snd_hda_jack_detect_enable(codec, spec->ext_mic_pin, ALC_MIC_EVENT);
1112 AC_VERB_SET_UNSOLICITED_ENABLE,
1113 AC_USRSP_EN | ALC_MIC_EVENT);
1114 if (spec->dock_mic_pin) 1111 if (spec->dock_mic_pin)
1115 snd_hda_codec_write_cache(codec, spec->dock_mic_pin, 0, 1112 snd_hda_jack_detect_enable(codec, spec->dock_mic_pin,
1116 AC_VERB_SET_UNSOLICITED_ENABLE, 1113 ALC_MIC_EVENT);
1117 AC_USRSP_EN | ALC_MIC_EVENT);
1118 1114
1119 spec->auto_mic_valid_imux = 1; 1115 spec->auto_mic_valid_imux = 1;
1120 spec->auto_mic = 1; 1116 spec->auto_mic = 1;
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 3b4ef0cba0e7..97c6df9db5e9 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -37,6 +37,7 @@
37#include "hda_codec.h" 37#include "hda_codec.h"
38#include "hda_local.h" 38#include "hda_local.h"
39#include "hda_beep.h" 39#include "hda_beep.h"
40#include "hda_jack.h"
40 41
41enum { 42enum {
42 STAC_VREF_EVENT = 1, 43 STAC_VREF_EVENT = 1,
@@ -4244,9 +4245,7 @@ static int enable_pin_detect(struct hda_codec *codec, hda_nid_t nid,
4244 if (tag < 0) 4245 if (tag < 0)
4245 return 0; 4246 return 0;
4246 } 4247 }
4247 snd_hda_codec_write_cache(codec, nid, 0, 4248 snd_hda_jack_detect_enable(codec, nid, tag);
4248 AC_VERB_SET_UNSOLICITED_ENABLE,
4249 AC_USRSP_EN | tag);
4250 return 1; 4249 return 1;
4251} 4250}
4252 4251
@@ -4795,24 +4794,11 @@ static void stac92xx_mic_detect(struct hda_codec *codec)
4795 mic->mux_idx); 4794 mic->mux_idx);
4796} 4795}
4797 4796
4798static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid) 4797static void handle_unsol_event(struct hda_codec *codec,
4799{ 4798 struct sigmatel_event *event)
4800 struct sigmatel_event *event = stac_get_event(codec, nid);
4801 if (!event)
4802 return;
4803 codec->patch_ops.unsol_event(codec, (unsigned)event->tag << 26);
4804}
4805
4806static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
4807{ 4799{
4808 struct sigmatel_spec *spec = codec->spec; 4800 struct sigmatel_spec *spec = codec->spec;
4809 struct sigmatel_event *event; 4801 int data;
4810 int tag, data;
4811
4812 tag = (res >> 26) & 0x7f;
4813 event = stac_get_event_from_tag(codec, tag);
4814 if (!event)
4815 return;
4816 4802
4817 switch (event->type) { 4803 switch (event->type) {
4818 case STAC_HP_EVENT: 4804 case STAC_HP_EVENT:
@@ -4862,6 +4848,28 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
4862 } 4848 }
4863} 4849}
4864 4850
4851static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid)
4852{
4853 struct sigmatel_event *event = stac_get_event(codec, nid);
4854 if (!event)
4855 return;
4856 handle_unsol_event(codec, event);
4857}
4858
4859static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
4860{
4861 struct sigmatel_spec *spec = codec->spec;
4862 struct sigmatel_event *event;
4863 int tag;
4864
4865 tag = (res >> 26) & 0x7f;
4866 event = stac_get_event_from_tag(codec, tag);
4867 if (!event)
4868 return;
4869 snd_hda_jack_set_dirty(codec, event->nid);
4870 handle_unsol_event(codec, event);
4871}
4872
4865static int hp_blike_system(u32 subsystem_id); 4873static int hp_blike_system(u32 subsystem_id);
4866 4874
4867static void set_hp_led_gpio(struct hda_codec *codec) 4875static void set_hp_led_gpio(struct hda_codec *codec)
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 431c0d417eeb..3467d0c23fe9 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -54,6 +54,7 @@
54#include <sound/asoundef.h> 54#include <sound/asoundef.h>
55#include "hda_codec.h" 55#include "hda_codec.h"
56#include "hda_local.h" 56#include "hda_local.h"
57#include "hda_jack.h"
57 58
58/* Pin Widget NID */ 59/* Pin Widget NID */
59#define VT1708_HP_PIN_NID 0x20 60#define VT1708_HP_PIN_NID 0x20
@@ -1708,6 +1709,8 @@ static void via_gpio_control(struct hda_codec *codec)
1708static void via_unsol_event(struct hda_codec *codec, 1709static void via_unsol_event(struct hda_codec *codec,
1709 unsigned int res) 1710 unsigned int res)
1710{ 1711{
1712 snd_hda_jack_set_dirty_all(codec); /* FIXME: to be more fine-grained */
1713
1711 res >>= 26; 1714 res >>= 26;
1712 1715
1713 if (res & VIA_JACK_EVENT) 1716 if (res & VIA_JACK_EVENT)
@@ -2729,9 +2732,8 @@ static void via_auto_init_unsol_event(struct hda_codec *codec)
2729 int i; 2732 int i;
2730 2733
2731 if (cfg->hp_pins[0] && is_jack_detectable(codec, cfg->hp_pins[0])) 2734 if (cfg->hp_pins[0] && is_jack_detectable(codec, cfg->hp_pins[0]))
2732 snd_hda_codec_write(codec, cfg->hp_pins[0], 0, 2735 snd_hda_jack_detect_enable(codec, cfg->hp_pins[0],
2733 AC_VERB_SET_UNSOLICITED_ENABLE, 2736 VIA_HP_EVENT | VIA_JACK_EVENT);
2734 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT);
2735 2737
2736 if (cfg->speaker_pins[0]) 2738 if (cfg->speaker_pins[0])
2737 ev = VIA_LINE_EVENT; 2739 ev = VIA_LINE_EVENT;
@@ -2740,16 +2742,14 @@ static void via_auto_init_unsol_event(struct hda_codec *codec)
2740 for (i = 0; i < cfg->line_outs; i++) { 2742 for (i = 0; i < cfg->line_outs; i++) {
2741 if (cfg->line_out_pins[i] && 2743 if (cfg->line_out_pins[i] &&
2742 is_jack_detectable(codec, cfg->line_out_pins[i])) 2744 is_jack_detectable(codec, cfg->line_out_pins[i]))
2743 snd_hda_codec_write(codec, cfg->line_out_pins[i], 0, 2745 snd_hda_jack_detect_enable(codec, cfg->line_out_pins[i],
2744 AC_VERB_SET_UNSOLICITED_ENABLE, 2746 ev | VIA_JACK_EVENT);
2745 AC_USRSP_EN | ev | VIA_JACK_EVENT);
2746 } 2747 }
2747 2748
2748 for (i = 0; i < cfg->num_inputs; i++) { 2749 for (i = 0; i < cfg->num_inputs; i++) {
2749 if (is_jack_detectable(codec, cfg->inputs[i].pin)) 2750 if (is_jack_detectable(codec, cfg->inputs[i].pin))
2750 snd_hda_codec_write(codec, cfg->inputs[i].pin, 0, 2751 snd_hda_jack_detect_enable(codec, cfg->inputs[i].pin,
2751 AC_VERB_SET_UNSOLICITED_ENABLE, 2752 VIA_JACK_EVENT);
2752 AC_USRSP_EN | VIA_JACK_EVENT);
2753 } 2753 }
2754} 2754}
2755 2755
@@ -2781,6 +2781,7 @@ static void vt1708_update_hp_jack_state(struct work_struct *work)
2781 vt1708_hp_work.work); 2781 vt1708_hp_work.work);
2782 if (spec->codec_type != VT1708) 2782 if (spec->codec_type != VT1708)
2783 return; 2783 return;
2784 snd_hda_jack_set_dirty_all(spec->codec);
2784 /* if jack state toggled */ 2785 /* if jack state toggled */
2785 if (spec->vt1708_hp_present 2786 if (spec->vt1708_hp_present
2786 != snd_hda_jack_detect(spec->codec, spec->autocfg.hp_pins[0])) { 2787 != snd_hda_jack_detect(spec->codec, spec->autocfg.hp_pins[0])) {