aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2014-09-22 04:12:16 -0400
committerTakashi Iwai <tiwai@suse.de>2014-09-22 04:12:16 -0400
commit7639913f7298ed23a3f026ebcbb3b4e8850bcc39 (patch)
tree26f08f061535015b748a96106f4869560e3afc63 /sound/pci/hda
parent4e9c58cb1219bcbcf6e698ed6541b275048bfa88 (diff)
parentf8fb117034847634bff8f02632151f7535981fa1 (diff)
Merge branch 'topic/hda-jack-rework' into for-next
This is a merge of rework of HD-audio jack event handling code. It extends the jack table to allow multiple callbacks.
Diffstat (limited to 'sound/pci/hda')
-rw-r--r--sound/pci/hda/ca0132_regs.h2
-rw-r--r--sound/pci/hda/hda_generic.c23
-rw-r--r--sound/pci/hda/hda_generic.h18
-rw-r--r--sound/pci/hda/hda_jack.c83
-rw-r--r--sound/pci/hda/hda_jack.h42
-rw-r--r--sound/pci/hda/patch_ca0132.c74
-rw-r--r--sound/pci/hda/patch_cirrus.c5
-rw-r--r--sound/pci/hda/patch_conexant.c12
-rw-r--r--sound/pci/hda/patch_hdmi.c18
-rw-r--r--sound/pci/hda/patch_realtek.c41
-rw-r--r--sound/pci/hda/patch_sigmatel.c79
-rw-r--r--sound/pci/hda/patch_via.c30
12 files changed, 198 insertions, 229 deletions
diff --git a/sound/pci/hda/ca0132_regs.h b/sound/pci/hda/ca0132_regs.h
index 07e760937d3c..8371274aa811 100644
--- a/sound/pci/hda/ca0132_regs.h
+++ b/sound/pci/hda/ca0132_regs.h
@@ -20,7 +20,7 @@
20 */ 20 */
21 21
22#ifndef __CA0132_REGS_H 22#ifndef __CA0132_REGS_H
23#define __CA0312_REGS_H 23#define __CA0132_REGS_H
24 24
25#define DSP_CHIP_OFFSET 0x100000 25#define DSP_CHIP_OFFSET 0x100000
26#define DSP_DBGCNTL_MODULE_OFFSET 0xE30 26#define DSP_DBGCNTL_MODULE_OFFSET 0xE30
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index 95121e818b4d..32a85f9cac4b 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -2032,7 +2032,8 @@ static int create_speaker_out_ctls(struct hda_codec *codec)
2032 * independent HP controls 2032 * independent HP controls
2033 */ 2033 */
2034 2034
2035static void call_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack); 2035static void call_hp_automute(struct hda_codec *codec,
2036 struct hda_jack_callback *jack);
2036static int indep_hp_info(struct snd_kcontrol *kcontrol, 2037static int indep_hp_info(struct snd_kcontrol *kcontrol,
2037 struct snd_ctl_elem_info *uinfo) 2038 struct snd_ctl_elem_info *uinfo)
2038{ 2039{
@@ -3948,7 +3949,8 @@ static void call_update_outputs(struct hda_codec *codec)
3948} 3949}
3949 3950
3950/* standard HP-automute helper */ 3951/* standard HP-automute helper */
3951void snd_hda_gen_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack) 3952void snd_hda_gen_hp_automute(struct hda_codec *codec,
3953 struct hda_jack_callback *jack)
3952{ 3954{
3953 struct hda_gen_spec *spec = codec->spec; 3955 struct hda_gen_spec *spec = codec->spec;
3954 hda_nid_t *pins = spec->autocfg.hp_pins; 3956 hda_nid_t *pins = spec->autocfg.hp_pins;
@@ -3968,7 +3970,8 @@ void snd_hda_gen_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack)
3968EXPORT_SYMBOL_GPL(snd_hda_gen_hp_automute); 3970EXPORT_SYMBOL_GPL(snd_hda_gen_hp_automute);
3969 3971
3970/* standard line-out-automute helper */ 3972/* standard line-out-automute helper */
3971void snd_hda_gen_line_automute(struct hda_codec *codec, struct hda_jack_tbl *jack) 3973void snd_hda_gen_line_automute(struct hda_codec *codec,
3974 struct hda_jack_callback *jack)
3972{ 3975{
3973 struct hda_gen_spec *spec = codec->spec; 3976 struct hda_gen_spec *spec = codec->spec;
3974 3977
@@ -3988,7 +3991,8 @@ void snd_hda_gen_line_automute(struct hda_codec *codec, struct hda_jack_tbl *jac
3988EXPORT_SYMBOL_GPL(snd_hda_gen_line_automute); 3991EXPORT_SYMBOL_GPL(snd_hda_gen_line_automute);
3989 3992
3990/* standard mic auto-switch helper */ 3993/* standard mic auto-switch helper */
3991void snd_hda_gen_mic_autoswitch(struct hda_codec *codec, struct hda_jack_tbl *jack) 3994void snd_hda_gen_mic_autoswitch(struct hda_codec *codec,
3995 struct hda_jack_callback *jack)
3992{ 3996{
3993 struct hda_gen_spec *spec = codec->spec; 3997 struct hda_gen_spec *spec = codec->spec;
3994 int i; 3998 int i;
@@ -4011,7 +4015,8 @@ void snd_hda_gen_mic_autoswitch(struct hda_codec *codec, struct hda_jack_tbl *ja
4011EXPORT_SYMBOL_GPL(snd_hda_gen_mic_autoswitch); 4015EXPORT_SYMBOL_GPL(snd_hda_gen_mic_autoswitch);
4012 4016
4013/* call appropriate hooks */ 4017/* call appropriate hooks */
4014static void call_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack) 4018static void call_hp_automute(struct hda_codec *codec,
4019 struct hda_jack_callback *jack)
4015{ 4020{
4016 struct hda_gen_spec *spec = codec->spec; 4021 struct hda_gen_spec *spec = codec->spec;
4017 if (spec->hp_automute_hook) 4022 if (spec->hp_automute_hook)
@@ -4021,7 +4026,7 @@ static void call_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack)
4021} 4026}
4022 4027
4023static void call_line_automute(struct hda_codec *codec, 4028static void call_line_automute(struct hda_codec *codec,
4024 struct hda_jack_tbl *jack) 4029 struct hda_jack_callback *jack)
4025{ 4030{
4026 struct hda_gen_spec *spec = codec->spec; 4031 struct hda_gen_spec *spec = codec->spec;
4027 if (spec->line_automute_hook) 4032 if (spec->line_automute_hook)
@@ -4031,7 +4036,7 @@ static void call_line_automute(struct hda_codec *codec,
4031} 4036}
4032 4037
4033static void call_mic_autoswitch(struct hda_codec *codec, 4038static void call_mic_autoswitch(struct hda_codec *codec,
4034 struct hda_jack_tbl *jack) 4039 struct hda_jack_callback *jack)
4035{ 4040{
4036 struct hda_gen_spec *spec = codec->spec; 4041 struct hda_gen_spec *spec = codec->spec;
4037 if (spec->mic_autoswitch_hook) 4042 if (spec->mic_autoswitch_hook)
@@ -4180,7 +4185,7 @@ static int check_auto_mute_availability(struct hda_codec *codec)
4180 if (!is_jack_detectable(codec, nid)) 4185 if (!is_jack_detectable(codec, nid))
4181 continue; 4186 continue;
4182 codec_dbg(codec, "Enable HP auto-muting on NID 0x%x\n", nid); 4187 codec_dbg(codec, "Enable HP auto-muting on NID 0x%x\n", nid);
4183 snd_hda_jack_detect_enable_callback(codec, nid, HDA_GEN_HP_EVENT, 4188 snd_hda_jack_detect_enable_callback(codec, nid,
4184 call_hp_automute); 4189 call_hp_automute);
4185 spec->detect_hp = 1; 4190 spec->detect_hp = 1;
4186 } 4191 }
@@ -4193,7 +4198,6 @@ static int check_auto_mute_availability(struct hda_codec *codec)
4193 continue; 4198 continue;
4194 codec_dbg(codec, "Enable Line-Out auto-muting on NID 0x%x\n", nid); 4199 codec_dbg(codec, "Enable Line-Out auto-muting on NID 0x%x\n", nid);
4195 snd_hda_jack_detect_enable_callback(codec, nid, 4200 snd_hda_jack_detect_enable_callback(codec, nid,
4196 HDA_GEN_FRONT_EVENT,
4197 call_line_automute); 4201 call_line_automute);
4198 spec->detect_lo = 1; 4202 spec->detect_lo = 1;
4199 } 4203 }
@@ -4235,7 +4239,6 @@ static bool auto_mic_check_imux(struct hda_codec *codec)
4235 for (i = 1; i < spec->am_num_entries; i++) 4239 for (i = 1; i < spec->am_num_entries; i++)
4236 snd_hda_jack_detect_enable_callback(codec, 4240 snd_hda_jack_detect_enable_callback(codec,
4237 spec->am_entry[i].pin, 4241 spec->am_entry[i].pin,
4238 HDA_GEN_MIC_EVENT,
4239 call_mic_autoswitch); 4242 call_mic_autoswitch);
4240 return true; 4243 return true;
4241} 4244}
diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h
index 3f95f1d3f1f8..61dd5153f512 100644
--- a/sound/pci/hda/hda_generic.h
+++ b/sound/pci/hda/hda_generic.h
@@ -12,12 +12,6 @@
12#ifndef __SOUND_HDA_GENERIC_H 12#ifndef __SOUND_HDA_GENERIC_H
13#define __SOUND_HDA_GENERIC_H 13#define __SOUND_HDA_GENERIC_H
14 14
15/* unsol event tags */
16enum {
17 HDA_GEN_HP_EVENT = 1, HDA_GEN_FRONT_EVENT, HDA_GEN_MIC_EVENT,
18 HDA_GEN_LAST_EVENT = HDA_GEN_MIC_EVENT
19};
20
21/* table entry for multi-io paths */ 15/* table entry for multi-io paths */
22struct hda_multi_io { 16struct hda_multi_io {
23 hda_nid_t pin; /* multi-io widget pin NID */ 17 hda_nid_t pin; /* multi-io widget pin NID */
@@ -290,11 +284,11 @@ struct hda_gen_spec {
290 284
291 /* automute / autoswitch hooks */ 285 /* automute / autoswitch hooks */
292 void (*hp_automute_hook)(struct hda_codec *codec, 286 void (*hp_automute_hook)(struct hda_codec *codec,
293 struct hda_jack_tbl *tbl); 287 struct hda_jack_callback *cb);
294 void (*line_automute_hook)(struct hda_codec *codec, 288 void (*line_automute_hook)(struct hda_codec *codec,
295 struct hda_jack_tbl *tbl); 289 struct hda_jack_callback *cb);
296 void (*mic_autoswitch_hook)(struct hda_codec *codec, 290 void (*mic_autoswitch_hook)(struct hda_codec *codec,
297 struct hda_jack_tbl *tbl); 291 struct hda_jack_callback *cb);
298}; 292};
299 293
300int snd_hda_gen_spec_init(struct hda_gen_spec *spec); 294int snd_hda_gen_spec_init(struct hda_gen_spec *spec);
@@ -326,11 +320,11 @@ int snd_hda_gen_build_pcms(struct hda_codec *codec);
326 320
327/* standard jack event callbacks */ 321/* standard jack event callbacks */
328void snd_hda_gen_hp_automute(struct hda_codec *codec, 322void snd_hda_gen_hp_automute(struct hda_codec *codec,
329 struct hda_jack_tbl *jack); 323 struct hda_jack_callback *jack);
330void snd_hda_gen_line_automute(struct hda_codec *codec, 324void snd_hda_gen_line_automute(struct hda_codec *codec,
331 struct hda_jack_tbl *jack); 325 struct hda_jack_callback *jack);
332void snd_hda_gen_mic_autoswitch(struct hda_codec *codec, 326void snd_hda_gen_mic_autoswitch(struct hda_codec *codec,
333 struct hda_jack_tbl *jack); 327 struct hda_jack_callback *jack);
334void snd_hda_gen_update_outputs(struct hda_codec *codec); 328void snd_hda_gen_update_outputs(struct hda_codec *codec);
335 329
336#ifdef CONFIG_PM 330#ifdef CONFIG_PM
diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c
index 9746d73cec52..f56765ae73a7 100644
--- a/sound/pci/hda/hda_jack.c
+++ b/sound/pci/hda/hda_jack.c
@@ -94,7 +94,7 @@ EXPORT_SYMBOL_GPL(snd_hda_jack_tbl_get_from_tag);
94/** 94/**
95 * snd_hda_jack_tbl_new - create a jack-table entry for the given NID 95 * snd_hda_jack_tbl_new - create a jack-table entry for the given NID
96 */ 96 */
97struct hda_jack_tbl * 97static struct hda_jack_tbl *
98snd_hda_jack_tbl_new(struct hda_codec *codec, hda_nid_t nid) 98snd_hda_jack_tbl_new(struct hda_codec *codec, hda_nid_t nid)
99{ 99{
100 struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid); 100 struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid);
@@ -108,21 +108,24 @@ snd_hda_jack_tbl_new(struct hda_codec *codec, hda_nid_t nid)
108 jack->tag = codec->jacktbl.used; 108 jack->tag = codec->jacktbl.used;
109 return jack; 109 return jack;
110} 110}
111EXPORT_SYMBOL_GPL(snd_hda_jack_tbl_new);
112 111
113void snd_hda_jack_tbl_clear(struct hda_codec *codec) 112void snd_hda_jack_tbl_clear(struct hda_codec *codec)
114{ 113{
114 struct hda_jack_tbl *jack = codec->jacktbl.list;
115 int i;
116
117 for (i = 0; i < codec->jacktbl.used; i++, jack++) {
118 struct hda_jack_callback *cb, *next;
115#ifdef CONFIG_SND_HDA_INPUT_JACK 119#ifdef CONFIG_SND_HDA_INPUT_JACK
116 /* free jack instances manually when clearing/reconfiguring */ 120 /* free jack instances manually when clearing/reconfiguring */
117 if (!codec->bus->shutdown && codec->jacktbl.list) { 121 if (!codec->bus->shutdown && jack->jack)
118 struct hda_jack_tbl *jack = codec->jacktbl.list; 122 snd_device_free(codec->bus->card, jack->jack);
119 int i; 123#endif
120 for (i = 0; i < codec->jacktbl.used; i++, jack++) { 124 for (cb = jack->callback; cb; cb = next) {
121 if (jack->jack) 125 next = cb->next;
122 snd_device_free(codec->bus->card, jack->jack); 126 kfree(cb);
123 } 127 }
124 } 128 }
125#endif
126 snd_array_free(&codec->jacktbl); 129 snd_array_free(&codec->jacktbl);
127} 130}
128 131
@@ -215,33 +218,49 @@ EXPORT_SYMBOL_GPL(snd_hda_jack_detect_state);
215 218
216/** 219/**
217 * snd_hda_jack_detect_enable - enable the jack-detection 220 * snd_hda_jack_detect_enable - enable the jack-detection
221 *
222 * In the case of error, the return value will be a pointer embedded with
223 * errno. Check and handle the return value appropriately with standard
224 * macros such as @IS_ERR() and @PTR_ERR().
218 */ 225 */
219int snd_hda_jack_detect_enable_callback(struct hda_codec *codec, hda_nid_t nid, 226struct hda_jack_callback *
220 unsigned char action, 227snd_hda_jack_detect_enable_callback(struct hda_codec *codec, hda_nid_t nid,
221 hda_jack_callback cb) 228 hda_jack_callback_fn func)
222{ 229{
223 struct hda_jack_tbl *jack = snd_hda_jack_tbl_new(codec, nid); 230 struct hda_jack_tbl *jack;
231 struct hda_jack_callback *callback = NULL;
232 int err;
233
234 jack = snd_hda_jack_tbl_new(codec, nid);
224 if (!jack) 235 if (!jack)
225 return -ENOMEM; 236 return ERR_PTR(-ENOMEM);
237 if (func) {
238 callback = kzalloc(sizeof(*callback), GFP_KERNEL);
239 if (!callback)
240 return ERR_PTR(-ENOMEM);
241 callback->func = func;
242 callback->tbl = jack;
243 callback->next = jack->callback;
244 jack->callback = callback;
245 }
246
226 if (jack->jack_detect) 247 if (jack->jack_detect)
227 return 0; /* already registered */ 248 return callback; /* already registered */
228 jack->jack_detect = 1; 249 jack->jack_detect = 1;
229 if (action)
230 jack->action = action;
231 if (cb)
232 jack->callback = cb;
233 if (codec->jackpoll_interval > 0) 250 if (codec->jackpoll_interval > 0)
234 return 0; /* No unsol if we're polling instead */ 251 return callback; /* No unsol if we're polling instead */
235 return snd_hda_codec_write_cache(codec, nid, 0, 252 err = snd_hda_codec_write_cache(codec, nid, 0,
236 AC_VERB_SET_UNSOLICITED_ENABLE, 253 AC_VERB_SET_UNSOLICITED_ENABLE,
237 AC_USRSP_EN | jack->tag); 254 AC_USRSP_EN | jack->tag);
255 if (err < 0)
256 return ERR_PTR(err);
257 return callback;
238} 258}
239EXPORT_SYMBOL_GPL(snd_hda_jack_detect_enable_callback); 259EXPORT_SYMBOL_GPL(snd_hda_jack_detect_enable_callback);
240 260
241int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid, 261int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid)
242 unsigned char action)
243{ 262{
244 return snd_hda_jack_detect_enable_callback(codec, nid, action, NULL); 263 return PTR_ERR_OR_ZERO(snd_hda_jack_detect_enable_callback(codec, nid, NULL));
245} 264}
246EXPORT_SYMBOL_GPL(snd_hda_jack_detect_enable); 265EXPORT_SYMBOL_GPL(snd_hda_jack_detect_enable);
247 266
@@ -431,7 +450,7 @@ static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid,
431 return err; 450 return err;
432 451
433 if (!phantom_jack) 452 if (!phantom_jack)
434 return snd_hda_jack_detect_enable(codec, nid, 0); 453 return snd_hda_jack_detect_enable(codec, nid);
435 return 0; 454 return 0;
436} 455}
437 456
@@ -498,13 +517,17 @@ EXPORT_SYMBOL_GPL(snd_hda_jack_add_kctls);
498static void call_jack_callback(struct hda_codec *codec, 517static void call_jack_callback(struct hda_codec *codec,
499 struct hda_jack_tbl *jack) 518 struct hda_jack_tbl *jack)
500{ 519{
501 if (jack->callback) 520 struct hda_jack_callback *cb;
502 jack->callback(codec, jack); 521
522 for (cb = jack->callback; cb; cb = cb->next)
523 cb->func(codec, cb);
503 if (jack->gated_jack) { 524 if (jack->gated_jack) {
504 struct hda_jack_tbl *gated = 525 struct hda_jack_tbl *gated =
505 snd_hda_jack_tbl_get(codec, jack->gated_jack); 526 snd_hda_jack_tbl_get(codec, jack->gated_jack);
506 if (gated && gated->callback) 527 if (gated) {
507 gated->callback(codec, gated); 528 for (cb = gated->callback; cb; cb = cb->next)
529 cb->func(codec, cb);
530 }
508 } 531 }
509} 532}
510 533
diff --git a/sound/pci/hda/hda_jack.h b/sound/pci/hda/hda_jack.h
index 46e1ea83ce3c..b41e0a3ea1fb 100644
--- a/sound/pci/hda/hda_jack.h
+++ b/sound/pci/hda/hda_jack.h
@@ -14,15 +14,21 @@
14 14
15struct auto_pin_cfg; 15struct auto_pin_cfg;
16struct hda_jack_tbl; 16struct hda_jack_tbl;
17struct hda_jack_callback;
17 18
18typedef void (*hda_jack_callback) (struct hda_codec *, struct hda_jack_tbl *); 19typedef void (*hda_jack_callback_fn) (struct hda_codec *, struct hda_jack_callback *);
20
21struct hda_jack_callback {
22 struct hda_jack_tbl *tbl;
23 hda_jack_callback_fn func;
24 unsigned int private_data; /* arbitrary data */
25 struct hda_jack_callback *next;
26};
19 27
20struct hda_jack_tbl { 28struct hda_jack_tbl {
21 hda_nid_t nid; 29 hda_nid_t nid;
22 unsigned char action; /* event action (0 = none) */
23 unsigned char tag; /* unsol event tag */ 30 unsigned char tag; /* unsol event tag */
24 unsigned int private_data; /* arbitrary data */ 31 struct hda_jack_callback *callback;
25 hda_jack_callback callback;
26 /* jack-detection stuff */ 32 /* jack-detection stuff */
27 unsigned int pin_sense; /* cached pin-sense value */ 33 unsigned int pin_sense; /* cached pin-sense value */
28 unsigned int jack_detect:1; /* capable of jack-detection? */ 34 unsigned int jack_detect:1; /* capable of jack-detection? */
@@ -43,34 +49,14 @@ snd_hda_jack_tbl_get(struct hda_codec *codec, hda_nid_t nid);
43struct hda_jack_tbl * 49struct hda_jack_tbl *
44snd_hda_jack_tbl_get_from_tag(struct hda_codec *codec, unsigned char tag); 50snd_hda_jack_tbl_get_from_tag(struct hda_codec *codec, unsigned char tag);
45 51
46struct hda_jack_tbl *
47snd_hda_jack_tbl_new(struct hda_codec *codec, hda_nid_t nid);
48void snd_hda_jack_tbl_clear(struct hda_codec *codec); 52void snd_hda_jack_tbl_clear(struct hda_codec *codec);
49 53
50/**
51 * snd_hda_jack_get_action - get jack-tbl entry for the tag
52 *
53 * Call this from the unsol event handler to get the assigned action for the
54 * event. This will mark the dirty flag for the later reporting, too.
55 */
56static inline unsigned char
57snd_hda_jack_get_action(struct hda_codec *codec, unsigned int tag)
58{
59 struct hda_jack_tbl *jack = snd_hda_jack_tbl_get_from_tag(codec, tag);
60 if (jack) {
61 jack->jack_dirty = 1;
62 return jack->action;
63 }
64 return 0;
65}
66
67void snd_hda_jack_set_dirty_all(struct hda_codec *codec); 54void snd_hda_jack_set_dirty_all(struct hda_codec *codec);
68 55
69int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid, 56int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid);
70 unsigned char action); 57struct hda_jack_callback *
71int snd_hda_jack_detect_enable_callback(struct hda_codec *codec, hda_nid_t nid, 58snd_hda_jack_detect_enable_callback(struct hda_codec *codec, hda_nid_t nid,
72 unsigned char action, 59 hda_jack_callback_fn cb);
73 hda_jack_callback cb);
74 60
75int snd_hda_jack_set_gating_jack(struct hda_codec *codec, hda_nid_t gated_nid, 61int snd_hda_jack_set_gating_jack(struct hda_codec *codec, hda_nid_t gated_nid,
76 hda_nid_t gating_nid); 62 hda_nid_t gating_nid);
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 5d8455e2dacd..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, UNSOL_TAG_HP);
4120 snd_hda_jack_detect_enable(codec, UNSOL_TAG_AMIC1, 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,36 +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 4410
4410 if (((res >> AC_UNSOL_RES_TAG_SHIFT) & 0x3f) == UNSOL_TAG_DSP) { 4411 /* Delay enabling the HP amp, to let the mic-detection
4411 ca0132_process_dsp_response(codec); 4412 * state machine run.
4412 } else { 4413 */
4413 res = snd_hda_jack_get_action(codec, 4414 cancel_delayed_work_sync(&spec->unsol_hp_work);
4414 (res >> AC_UNSOL_RES_TAG_SHIFT) & 0x3f); 4415 queue_delayed_work(codec->bus->workq, &spec->unsol_hp_work,
4415 4416 msecs_to_jiffies(500));
4416 codec_dbg(codec, "snd_hda_jack_get_action: 0x%x\n", res); 4417 cb->tbl->block_report = 1;
4417 4418}
4418 switch (res) { 4419
4419 case UNSOL_TAG_HP: 4420static void amic_callback(struct hda_codec *codec, struct hda_jack_callback *cb)
4420 /* Delay enabling the HP amp, to let the mic-detection 4421{
4421 * state machine run. 4422 ca0132_select_mic(codec);
4422 */ 4423}
4423 cancel_delayed_work_sync(&spec->unsol_hp_work); 4424
4424 queue_delayed_work(codec->bus->workq, 4425static void ca0132_init_unsol(struct hda_codec *codec)
4425 &spec->unsol_hp_work, 4426{
4426 msecs_to_jiffies(500)); 4427 snd_hda_jack_detect_enable_callback(codec, UNSOL_TAG_HP, hp_callback);
4427 break; 4428 snd_hda_jack_detect_enable_callback(codec, UNSOL_TAG_AMIC1,
4428 case UNSOL_TAG_AMIC1: 4429 amic_callback);
4429 ca0132_select_mic(codec); 4430 snd_hda_jack_detect_enable_callback(codec, UNSOL_TAG_DSP,
4430 snd_hda_jack_report_sync(codec); 4431 ca0132_process_dsp_response);
4431 break;
4432 default:
4433 break;
4434 }
4435 }
4436} 4432}
4437 4433
4438/* 4434/*
@@ -4443,8 +4439,6 @@ static void ca0132_unsol_event(struct hda_codec *codec, unsigned int res)
4443static struct hda_verb ca0132_base_init_verbs[] = { 4439static struct hda_verb ca0132_base_init_verbs[] = {
4444 /*enable ct extension*/ 4440 /*enable ct extension*/
4445 {0x15, VENDOR_CHIPIO_CT_EXTENSIONS_ENABLE, 0x1}, 4441 {0x15, VENDOR_CHIPIO_CT_EXTENSIONS_ENABLE, 0x1},
4446 /*enable DSP node unsol, needed for DSP download*/
4447 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | UNSOL_TAG_DSP},
4448 {} 4442 {}
4449}; 4443};
4450 4444
@@ -4561,6 +4555,8 @@ static int ca0132_init(struct hda_codec *codec)
4561 4555
4562 snd_hda_power_up(codec); 4556 snd_hda_power_up(codec);
4563 4557
4558 ca0132_init_unsol(codec);
4559
4564 ca0132_init_params(codec); 4560 ca0132_init_params(codec);
4565 ca0132_init_flags(codec); 4561 ca0132_init_flags(codec);
4566 snd_hda_sequence_write(codec, spec->base_init_verbs); 4562 snd_hda_sequence_write(codec, spec->base_init_verbs);
@@ -4583,8 +4579,6 @@ static int ca0132_init(struct hda_codec *codec)
4583 for (i = 0; i < spec->num_init_verbs; i++) 4579 for (i = 0; i < spec->num_init_verbs; i++)
4584 snd_hda_sequence_write(codec, spec->init_verbs[i]); 4580 snd_hda_sequence_write(codec, spec->init_verbs[i]);
4585 4581
4586 ca0132_init_unsol(codec);
4587
4588 ca0132_select_out(codec); 4582 ca0132_select_out(codec);
4589 ca0132_select_mic(codec); 4583 ca0132_select_mic(codec);
4590 4584
@@ -4612,7 +4606,7 @@ static struct hda_codec_ops ca0132_patch_ops = {
4612 .build_pcms = ca0132_build_pcms, 4606 .build_pcms = ca0132_build_pcms,
4613 .init = ca0132_init, 4607 .init = ca0132_init,
4614 .free = ca0132_free, 4608 .free = ca0132_free,
4615 .unsol_event = ca0132_unsol_event, 4609 .unsol_event = snd_hda_jack_unsol_event,
4616}; 4610};
4617 4611
4618static void ca0132_config(struct hda_codec *codec) 4612static void ca0132_config(struct hda_codec *codec)
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index 3db724eaa53c..1589c9bcce3e 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -135,8 +135,6 @@ enum {
135#define CS421X_IDX_DAC_CFG 0x03 135#define CS421X_IDX_DAC_CFG 0x03
136#define CS421X_IDX_SPK_CTL 0x04 136#define CS421X_IDX_SPK_CTL 0x04
137 137
138#define SPDIF_EVENT 0x04
139
140/* Cirrus Logic CS4213 is like CS4210 but does not have SPDIF input/output */ 138/* Cirrus Logic CS4213 is like CS4210 but does not have SPDIF input/output */
141#define CS4213_VENDOR_NID 0x09 139#define CS4213_VENDOR_NID 0x09
142 140
@@ -984,7 +982,7 @@ static void cs4210_pinmux_init(struct hda_codec *codec)
984} 982}
985 983
986static void cs4210_spdif_automute(struct hda_codec *codec, 984static void cs4210_spdif_automute(struct hda_codec *codec,
987 struct hda_jack_tbl *tbl) 985 struct hda_jack_callback *tbl)
988{ 986{
989 struct cs_spec *spec = codec->spec; 987 struct cs_spec *spec = codec->spec;
990 bool spdif_present = false; 988 bool spdif_present = false;
@@ -1019,7 +1017,6 @@ static void parse_cs421x_digital(struct hda_codec *codec)
1019 if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) { 1017 if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) {
1020 spec->spdif_detect = 1; 1018 spec->spdif_detect = 1;
1021 snd_hda_jack_detect_enable_callback(codec, nid, 1019 snd_hda_jack_detect_enable_callback(codec, nid,
1022 SPDIF_EVENT,
1023 cs4210_spdif_automute); 1020 cs4210_spdif_automute);
1024 } 1021 }
1025 } 1022 }
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index c0b03c112187..d5b0582daaf0 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -216,6 +216,7 @@ enum {
216 CXT_FIXUP_HEADPHONE_MIC_PIN, 216 CXT_FIXUP_HEADPHONE_MIC_PIN,
217 CXT_FIXUP_HEADPHONE_MIC, 217 CXT_FIXUP_HEADPHONE_MIC,
218 CXT_FIXUP_GPIO1, 218 CXT_FIXUP_GPIO1,
219 CXT_FIXUP_ASPIRE_DMIC,
219 CXT_FIXUP_THINKPAD_ACPI, 220 CXT_FIXUP_THINKPAD_ACPI,
220 CXT_FIXUP_OLPC_XO, 221 CXT_FIXUP_OLPC_XO,
221 CXT_FIXUP_CAP_MIX_AMP, 222 CXT_FIXUP_CAP_MIX_AMP,
@@ -392,7 +393,8 @@ static void olpc_xo_update_mic_pins(struct hda_codec *codec)
392} 393}
393 394
394/* mic_autoswitch hook */ 395/* mic_autoswitch hook */
395static void olpc_xo_automic(struct hda_codec *codec, struct hda_jack_tbl *jack) 396static void olpc_xo_automic(struct hda_codec *codec,
397 struct hda_jack_callback *jack)
396{ 398{
397 struct conexant_spec *spec = codec->spec; 399 struct conexant_spec *spec = codec->spec;
398 int saved_cached_write = codec->cached_write; 400 int saved_cached_write = codec->cached_write;
@@ -663,6 +665,12 @@ static const struct hda_fixup cxt_fixups[] = {
663 { } 665 { }
664 }, 666 },
665 }, 667 },
668 [CXT_FIXUP_ASPIRE_DMIC] = {
669 .type = HDA_FIXUP_FUNC,
670 .v.func = cxt_fixup_stereo_dmic,
671 .chained = true,
672 .chain_id = CXT_FIXUP_GPIO1,
673 },
666 [CXT_FIXUP_THINKPAD_ACPI] = { 674 [CXT_FIXUP_THINKPAD_ACPI] = {
667 .type = HDA_FIXUP_FUNC, 675 .type = HDA_FIXUP_FUNC,
668 .v.func = hda_fixup_thinkpad_acpi, 676 .v.func = hda_fixup_thinkpad_acpi,
@@ -743,7 +751,7 @@ static const struct hda_model_fixup cxt5051_fixup_models[] = {
743 751
744static const struct snd_pci_quirk cxt5066_fixups[] = { 752static const struct snd_pci_quirk cxt5066_fixups[] = {
745 SND_PCI_QUIRK(0x1025, 0x0543, "Acer Aspire One 522", CXT_FIXUP_STEREO_DMIC), 753 SND_PCI_QUIRK(0x1025, 0x0543, "Acer Aspire One 522", CXT_FIXUP_STEREO_DMIC),
746 SND_PCI_QUIRK(0x1025, 0x054c, "Acer Aspire 3830TG", CXT_FIXUP_GPIO1), 754 SND_PCI_QUIRK(0x1025, 0x054c, "Acer Aspire 3830TG", CXT_FIXUP_ASPIRE_DMIC),
747 SND_PCI_QUIRK(0x1043, 0x138d, "Asus", CXT_FIXUP_HEADPHONE_MIC_PIN), 755 SND_PCI_QUIRK(0x1043, 0x138d, "Asus", CXT_FIXUP_HEADPHONE_MIC_PIN),
748 SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT_FIXUP_OLPC_XO), 756 SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT_FIXUP_OLPC_XO),
749 SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410), 757 SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410),
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 99d7d7fecaad..39862e98551c 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -1163,17 +1163,23 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec,
1163 1163
1164static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll); 1164static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll);
1165 1165
1166static void jack_callback(struct hda_codec *codec, struct hda_jack_tbl *jack) 1166static void check_presence_and_report(struct hda_codec *codec, hda_nid_t nid)
1167{ 1167{
1168 struct hdmi_spec *spec = codec->spec; 1168 struct hdmi_spec *spec = codec->spec;
1169 int pin_idx = pin_nid_to_pin_index(codec, jack->nid); 1169 int pin_idx = pin_nid_to_pin_index(codec, nid);
1170
1170 if (pin_idx < 0) 1171 if (pin_idx < 0)
1171 return; 1172 return;
1172
1173 if (hdmi_present_sense(get_pin(spec, pin_idx), 1)) 1173 if (hdmi_present_sense(get_pin(spec, pin_idx), 1))
1174 snd_hda_jack_report_sync(codec); 1174 snd_hda_jack_report_sync(codec);
1175} 1175}
1176 1176
1177static void jack_callback(struct hda_codec *codec,
1178 struct hda_jack_callback *jack)
1179{
1180 check_presence_and_report(codec, jack->tbl->nid);
1181}
1182
1177static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) 1183static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
1178{ 1184{
1179 int tag = res >> AC_UNSOL_RES_TAG_SHIFT; 1185 int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
@@ -1190,7 +1196,7 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
1190 codec->addr, jack->nid, dev_entry, !!(res & AC_UNSOL_RES_IA), 1196 codec->addr, jack->nid, dev_entry, !!(res & AC_UNSOL_RES_IA),
1191 !!(res & AC_UNSOL_RES_PD), !!(res & AC_UNSOL_RES_ELDV)); 1197 !!(res & AC_UNSOL_RES_PD), !!(res & AC_UNSOL_RES_ELDV));
1192 1198
1193 jack_callback(codec, jack); 1199 check_presence_and_report(codec, jack->nid);
1194} 1200}
1195 1201
1196static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res) 1202static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res)
@@ -2165,7 +2171,7 @@ static int generic_hdmi_init(struct hda_codec *codec)
2165 hda_nid_t pin_nid = per_pin->pin_nid; 2171 hda_nid_t pin_nid = per_pin->pin_nid;
2166 2172
2167 hdmi_init_pin(codec, pin_nid); 2173 hdmi_init_pin(codec, pin_nid);
2168 snd_hda_jack_detect_enable_callback(codec, pin_nid, pin_nid, 2174 snd_hda_jack_detect_enable_callback(codec, pin_nid,
2169 codec->jackpoll_interval > 0 ? jack_callback : NULL); 2175 codec->jackpoll_interval > 0 ? jack_callback : NULL);
2170 } 2176 }
2171 return 0; 2177 return 0;
@@ -2428,7 +2434,7 @@ static int simple_playback_init(struct hda_codec *codec)
2428 if (get_wcaps(codec, pin) & AC_WCAP_OUT_AMP) 2434 if (get_wcaps(codec, pin) & AC_WCAP_OUT_AMP)
2429 snd_hda_codec_write(codec, pin, 0, AC_VERB_SET_AMP_GAIN_MUTE, 2435 snd_hda_codec_write(codec, pin, 0, AC_VERB_SET_AMP_GAIN_MUTE,
2430 AMP_OUT_UNMUTE); 2436 AMP_OUT_UNMUTE);
2431 snd_hda_jack_detect_enable(codec, pin, pin); 2437 snd_hda_jack_detect_enable(codec, pin);
2432 return 0; 2438 return 0;
2433} 2439}
2434 2440
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index cbc4d25e4538..a109fdb085f9 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -40,9 +40,6 @@
40/* keep halting ALC5505 DSP, for power saving */ 40/* keep halting ALC5505 DSP, for power saving */
41#define HALT_REALTEK_ALC5505 41#define HALT_REALTEK_ALC5505
42 42
43/* unsol event tags */
44#define ALC_DCVOL_EVENT 0x08
45
46/* for GPIO Poll */ 43/* for GPIO Poll */
47#define GPIO_MASK 0x03 44#define GPIO_MASK 0x03
48 45
@@ -267,7 +264,8 @@ static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
267} 264}
268 265
269/* update the master volume per volume-knob's unsol event */ 266/* update the master volume per volume-knob's unsol event */
270static void alc_update_knob_master(struct hda_codec *codec, struct hda_jack_tbl *jack) 267static void alc_update_knob_master(struct hda_codec *codec,
268 struct hda_jack_callback *jack)
271{ 269{
272 unsigned int val; 270 unsigned int val;
273 struct snd_kcontrol *kctl; 271 struct snd_kcontrol *kctl;
@@ -279,7 +277,7 @@ static void alc_update_knob_master(struct hda_codec *codec, struct hda_jack_tbl
279 uctl = kzalloc(sizeof(*uctl), GFP_KERNEL); 277 uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
280 if (!uctl) 278 if (!uctl)
281 return; 279 return;
282 val = snd_hda_codec_read(codec, jack->nid, 0, 280 val = snd_hda_codec_read(codec, jack->tbl->nid, 0,
283 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0); 281 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
284 val &= HDA_AMP_VOLMASK; 282 val &= HDA_AMP_VOLMASK;
285 uctl->value.integer.value[0] = val; 283 uctl->value.integer.value[0] = val;
@@ -373,6 +371,7 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type)
373 case 0x10ec0885: 371 case 0x10ec0885:
374 case 0x10ec0887: 372 case 0x10ec0887:
375 /*case 0x10ec0889:*/ /* this causes an SPDIF problem */ 373 /*case 0x10ec0889:*/ /* this causes an SPDIF problem */
374 case 0x10ec0900:
376 alc889_coef_init(codec); 375 alc889_coef_init(codec);
377 break; 376 break;
378 case 0x10ec0888: 377 case 0x10ec0888:
@@ -1129,7 +1128,8 @@ static void alc880_fixup_vol_knob(struct hda_codec *codec,
1129 const struct hda_fixup *fix, int action) 1128 const struct hda_fixup *fix, int action)
1130{ 1129{
1131 if (action == HDA_FIXUP_ACT_PROBE) 1130 if (action == HDA_FIXUP_ACT_PROBE)
1132 snd_hda_jack_detect_enable_callback(codec, 0x21, ALC_DCVOL_EVENT, alc_update_knob_master); 1131 snd_hda_jack_detect_enable_callback(codec, 0x21,
1132 alc_update_knob_master);
1133} 1133}
1134 1134
1135static const struct hda_fixup alc880_fixups[] = { 1135static const struct hda_fixup alc880_fixups[] = {
@@ -1592,7 +1592,7 @@ static void alc260_fixup_gpio1_toggle(struct hda_codec *codec,
1592 spec->gen.detect_hp = 1; 1592 spec->gen.detect_hp = 1;
1593 spec->gen.automute_speaker = 1; 1593 spec->gen.automute_speaker = 1;
1594 spec->gen.autocfg.hp_pins[0] = 0x0f; /* copy it for automute */ 1594 spec->gen.autocfg.hp_pins[0] = 0x0f; /* copy it for automute */
1595 snd_hda_jack_detect_enable_callback(codec, 0x0f, HDA_GEN_HP_EVENT, 1595 snd_hda_jack_detect_enable_callback(codec, 0x0f,
1596 snd_hda_gen_hp_automute); 1596 snd_hda_gen_hp_automute);
1597 snd_hda_add_verbs(codec, alc_gpio1_init_verbs); 1597 snd_hda_add_verbs(codec, alc_gpio1_init_verbs);
1598 } 1598 }
@@ -2346,6 +2346,7 @@ static int patch_alc882(struct hda_codec *codec)
2346 switch (codec->vendor_id) { 2346 switch (codec->vendor_id) {
2347 case 0x10ec0882: 2347 case 0x10ec0882:
2348 case 0x10ec0885: 2348 case 0x10ec0885:
2349 case 0x10ec0900:
2349 break; 2350 break;
2350 default: 2351 default:
2351 /* ALC883 and variants */ 2352 /* ALC883 and variants */
@@ -3272,7 +3273,7 @@ static void alc269_fixup_quanta_mute(struct hda_codec *codec,
3272} 3273}
3273 3274
3274static void alc269_x101_hp_automute_hook(struct hda_codec *codec, 3275static void alc269_x101_hp_automute_hook(struct hda_codec *codec,
3275 struct hda_jack_tbl *jack) 3276 struct hda_jack_callback *jack)
3276{ 3277{
3277 struct alc_spec *spec = codec->spec; 3278 struct alc_spec *spec = codec->spec;
3278 int vref; 3279 int vref;
@@ -3926,7 +3927,8 @@ static void alc_update_headset_mode_hook(struct hda_codec *codec,
3926 alc_update_headset_mode(codec); 3927 alc_update_headset_mode(codec);
3927} 3928}
3928 3929
3929static void alc_update_headset_jack_cb(struct hda_codec *codec, struct hda_jack_tbl *jack) 3930static void alc_update_headset_jack_cb(struct hda_codec *codec,
3931 struct hda_jack_callback *jack)
3930{ 3932{
3931 struct alc_spec *spec = codec->spec; 3933 struct alc_spec *spec = codec->spec;
3932 spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN; 3934 spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN;
@@ -4166,7 +4168,7 @@ static void alc269_fixup_limit_int_mic_boost(struct hda_codec *codec,
4166} 4168}
4167 4169
4168static void alc283_hp_automute_hook(struct hda_codec *codec, 4170static void alc283_hp_automute_hook(struct hda_codec *codec,
4169 struct hda_jack_tbl *jack) 4171 struct hda_jack_callback *jack)
4170{ 4172{
4171 struct alc_spec *spec = codec->spec; 4173 struct alc_spec *spec = codec->spec;
4172 int vref; 4174 int vref;
@@ -4252,7 +4254,6 @@ static void alc282_fixup_asus_tx300(struct hda_codec *codec,
4252 spec->gen.auto_mute_via_amp = 1; 4254 spec->gen.auto_mute_via_amp = 1;
4253 spec->gen.automute_hook = asus_tx300_automute; 4255 spec->gen.automute_hook = asus_tx300_automute;
4254 snd_hda_jack_detect_enable_callback(codec, 0x1b, 4256 snd_hda_jack_detect_enable_callback(codec, 0x1b,
4255 HDA_GEN_HP_EVENT,
4256 snd_hda_gen_hp_automute); 4257 snd_hda_gen_hp_automute);
4257 break; 4258 break;
4258 case HDA_FIXUP_ACT_BUILD: 4259 case HDA_FIXUP_ACT_BUILD:
@@ -4353,6 +4354,7 @@ enum {
4353 ALC292_FIXUP_TPT440_DOCK, 4354 ALC292_FIXUP_TPT440_DOCK,
4354 ALC283_FIXUP_BXBT2807_MIC, 4355 ALC283_FIXUP_BXBT2807_MIC,
4355 ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED, 4356 ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED,
4357 ALC282_FIXUP_ASPIRE_V5_PINS,
4356}; 4358};
4357 4359
4358static const struct hda_fixup alc269_fixups[] = { 4360static const struct hda_fixup alc269_fixups[] = {
@@ -4800,6 +4802,22 @@ static const struct hda_fixup alc269_fixups[] = {
4800 .chained_before = true, 4802 .chained_before = true,
4801 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE 4803 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
4802 }, 4804 },
4805 [ALC282_FIXUP_ASPIRE_V5_PINS] = {
4806 .type = HDA_FIXUP_PINS,
4807 .v.pins = (const struct hda_pintbl[]) {
4808 { 0x12, 0x90a60130 },
4809 { 0x14, 0x90170110 },
4810 { 0x17, 0x40000008 },
4811 { 0x18, 0x411111f0 },
4812 { 0x19, 0x411111f0 },
4813 { 0x1a, 0x411111f0 },
4814 { 0x1b, 0x411111f0 },
4815 { 0x1d, 0x40f89b2d },
4816 { 0x1e, 0x411111f0 },
4817 { 0x21, 0x0321101f },
4818 { },
4819 },
4820 },
4803 4821
4804}; 4822};
4805 4823
@@ -4811,6 +4829,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
4811 SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK), 4829 SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK),
4812 SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK), 4830 SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK),
4813 SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572), 4831 SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
4832 SND_PCI_QUIRK(0x1025, 0x079b, "Acer Aspire V5-573G", ALC282_FIXUP_ASPIRE_V5_PINS),
4814 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), 4833 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
4815 SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER), 4834 SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER),
4816 SND_PCI_QUIRK(0x1028, 0x05f4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 4835 SND_PCI_QUIRK(0x1028, 0x05f4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index f26ec04a29b5..4f6413e01c13 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -40,11 +40,6 @@
40#include "hda_generic.h" 40#include "hda_generic.h"
41 41
42enum { 42enum {
43 STAC_VREF_EVENT = 8,
44 STAC_PWR_EVENT,
45};
46
47enum {
48 STAC_REF, 43 STAC_REF,
49 STAC_9200_OQO, 44 STAC_9200_OQO,
50 STAC_9200_DELL_D21, 45 STAC_9200_DELL_D21,
@@ -486,7 +481,7 @@ static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid,
486 481
487/* update power bit per jack plug/unplug */ 482/* update power bit per jack plug/unplug */
488static void jack_update_power(struct hda_codec *codec, 483static void jack_update_power(struct hda_codec *codec,
489 struct hda_jack_tbl *jack) 484 struct hda_jack_callback *jack)
490{ 485{
491 struct sigmatel_spec *spec = codec->spec; 486 struct sigmatel_spec *spec = codec->spec;
492 int i; 487 int i;
@@ -494,9 +489,9 @@ static void jack_update_power(struct hda_codec *codec,
494 if (!spec->num_pwrs) 489 if (!spec->num_pwrs)
495 return; 490 return;
496 491
497 if (jack && jack->nid) { 492 if (jack && jack->tbl->nid) {
498 stac_toggle_power_map(codec, jack->nid, 493 stac_toggle_power_map(codec, jack->tbl->nid,
499 snd_hda_jack_detect(codec, jack->nid), 494 snd_hda_jack_detect(codec, jack->tbl->nid),
500 true); 495 true);
501 return; 496 return;
502 } 497 }
@@ -504,42 +499,19 @@ static void jack_update_power(struct hda_codec *codec,
504 /* update all jacks */ 499 /* update all jacks */
505 for (i = 0; i < spec->num_pwrs; i++) { 500 for (i = 0; i < spec->num_pwrs; i++) {
506 hda_nid_t nid = spec->pwr_nids[i]; 501 hda_nid_t nid = spec->pwr_nids[i];
507 jack = snd_hda_jack_tbl_get(codec, nid); 502 if (!snd_hda_jack_tbl_get(codec, nid))
508 if (!jack || !jack->action)
509 continue; 503 continue;
510 if (jack->action == STAC_PWR_EVENT || 504 stac_toggle_power_map(codec, nid,
511 jack->action <= HDA_GEN_LAST_EVENT) 505 snd_hda_jack_detect(codec, nid),
512 stac_toggle_power_map(codec, nid, 506 false);
513 snd_hda_jack_detect(codec, nid),
514 false);
515 } 507 }
516 508
517 snd_hda_codec_write(codec, codec->afg, 0, AC_VERB_IDT_SET_POWER_MAP, 509 snd_hda_codec_write(codec, codec->afg, 0, AC_VERB_IDT_SET_POWER_MAP,
518 spec->power_map_bits); 510 spec->power_map_bits);
519} 511}
520 512
521static void stac_hp_automute(struct hda_codec *codec, 513static void stac_vref_event(struct hda_codec *codec,
522 struct hda_jack_tbl *jack) 514 struct hda_jack_callback *event)
523{
524 snd_hda_gen_hp_automute(codec, jack);
525 jack_update_power(codec, jack);
526}
527
528static void stac_line_automute(struct hda_codec *codec,
529 struct hda_jack_tbl *jack)
530{
531 snd_hda_gen_line_automute(codec, jack);
532 jack_update_power(codec, jack);
533}
534
535static void stac_mic_autoswitch(struct hda_codec *codec,
536 struct hda_jack_tbl *jack)
537{
538 snd_hda_gen_mic_autoswitch(codec, jack);
539 jack_update_power(codec, jack);
540}
541
542static void stac_vref_event(struct hda_codec *codec, struct hda_jack_tbl *event)
543{ 515{
544 unsigned int data; 516 unsigned int data;
545 517
@@ -562,13 +534,10 @@ static void stac_init_power_map(struct hda_codec *codec)
562 hda_nid_t nid = spec->pwr_nids[i]; 534 hda_nid_t nid = spec->pwr_nids[i];
563 unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid); 535 unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid);
564 def_conf = get_defcfg_connect(def_conf); 536 def_conf = get_defcfg_connect(def_conf);
565 if (snd_hda_jack_tbl_get(codec, nid))
566 continue;
567 if (def_conf == AC_JACK_PORT_COMPLEX && 537 if (def_conf == AC_JACK_PORT_COMPLEX &&
568 !(spec->vref_mute_led_nid == nid || 538 spec->vref_mute_led_nid != nid &&
569 is_jack_detectable(codec, nid))) { 539 is_jack_detectable(codec, nid)) {
570 snd_hda_jack_detect_enable_callback(codec, nid, 540 snd_hda_jack_detect_enable_callback(codec, nid,
571 STAC_PWR_EVENT,
572 jack_update_power); 541 jack_update_power);
573 } else { 542 } else {
574 if (def_conf == AC_JACK_PORT_NONE) 543 if (def_conf == AC_JACK_PORT_NONE)
@@ -3019,7 +2988,7 @@ static void stac92hd71bxx_fixup_hp_m4(struct hda_codec *codec,
3019 const struct hda_fixup *fix, int action) 2988 const struct hda_fixup *fix, int action)
3020{ 2989{
3021 struct sigmatel_spec *spec = codec->spec; 2990 struct sigmatel_spec *spec = codec->spec;
3022 struct hda_jack_tbl *jack; 2991 struct hda_jack_callback *jack;
3023 2992
3024 if (action != HDA_FIXUP_ACT_PRE_PROBE) 2993 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3025 return; 2994 return;
@@ -3027,11 +2996,9 @@ static void stac92hd71bxx_fixup_hp_m4(struct hda_codec *codec,
3027 /* Enable VREF power saving on GPIO1 detect */ 2996 /* Enable VREF power saving on GPIO1 detect */
3028 snd_hda_codec_write_cache(codec, codec->afg, 0, 2997 snd_hda_codec_write_cache(codec, codec->afg, 0,
3029 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x02); 2998 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x02);
3030 snd_hda_jack_detect_enable_callback(codec, codec->afg, 2999 jack = snd_hda_jack_detect_enable_callback(codec, codec->afg,
3031 STAC_VREF_EVENT, 3000 stac_vref_event);
3032 stac_vref_event); 3001 if (!IS_ERR(jack))
3033 jack = snd_hda_jack_tbl_get(codec, codec->afg);
3034 if (jack)
3035 jack->private_data = 0x02; 3002 jack->private_data = 0x02;
3036 3003
3037 spec->gpio_mask |= 0x02; 3004 spec->gpio_mask |= 0x02;
@@ -4043,7 +4010,7 @@ static void stac9205_fixup_dell_m43(struct hda_codec *codec,
4043 const struct hda_fixup *fix, int action) 4010 const struct hda_fixup *fix, int action)
4044{ 4011{
4045 struct sigmatel_spec *spec = codec->spec; 4012 struct sigmatel_spec *spec = codec->spec;
4046 struct hda_jack_tbl *jack; 4013 struct hda_jack_callback *jack;
4047 4014
4048 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 4015 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4049 snd_hda_apply_pincfgs(codec, dell_9205_m43_pin_configs); 4016 snd_hda_apply_pincfgs(codec, dell_9205_m43_pin_configs);
@@ -4051,11 +4018,9 @@ static void stac9205_fixup_dell_m43(struct hda_codec *codec,
4051 /* Enable unsol response for GPIO4/Dock HP connection */ 4018 /* Enable unsol response for GPIO4/Dock HP connection */
4052 snd_hda_codec_write_cache(codec, codec->afg, 0, 4019 snd_hda_codec_write_cache(codec, codec->afg, 0,
4053 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x10); 4020 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x10);
4054 snd_hda_jack_detect_enable_callback(codec, codec->afg, 4021 jack = snd_hda_jack_detect_enable_callback(codec, codec->afg,
4055 STAC_VREF_EVENT, 4022 stac_vref_event);
4056 stac_vref_event); 4023 if (!IS_ERR(jack))
4057 jack = snd_hda_jack_tbl_get(codec, codec->afg);
4058 if (jack)
4059 jack->private_data = 0x01; 4024 jack->private_data = 0x01;
4060 4025
4061 spec->gpio_dir = 0x0b; 4026 spec->gpio_dir = 0x0b;
@@ -4218,9 +4183,6 @@ static int stac_parse_auto_config(struct hda_codec *codec)
4218 spec->gen.pcm_capture_hook = stac_capture_pcm_hook; 4183 spec->gen.pcm_capture_hook = stac_capture_pcm_hook;
4219 4184
4220 spec->gen.automute_hook = stac_update_outputs; 4185 spec->gen.automute_hook = stac_update_outputs;
4221 spec->gen.hp_automute_hook = stac_hp_automute;
4222 spec->gen.line_automute_hook = stac_line_automute;
4223 spec->gen.mic_autoswitch_hook = stac_mic_autoswitch;
4224 4186
4225 err = snd_hda_gen_parse_auto_config(codec, &spec->gen.autocfg); 4187 err = snd_hda_gen_parse_auto_config(codec, &spec->gen.autocfg);
4226 if (err < 0) 4188 if (err < 0)
@@ -4277,7 +4239,6 @@ static int stac_parse_auto_config(struct hda_codec *codec)
4277 return 0; 4239 return 0;
4278} 4240}
4279 4241
4280
4281static int stac_init(struct hda_codec *codec) 4242static int stac_init(struct hda_codec *codec)
4282{ 4243{
4283 struct sigmatel_spec *spec = codec->spec; 4244 struct sigmatel_spec *spec = codec->spec;
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 778166259b3e..6c206b6c8d65 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -118,7 +118,6 @@ static void via_playback_pcm_hook(struct hda_pcm_stream *hinfo,
118 struct hda_codec *codec, 118 struct hda_codec *codec,
119 struct snd_pcm_substream *substream, 119 struct snd_pcm_substream *substream,
120 int action); 120 int action);
121static void via_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *tbl);
122 121
123static struct via_spec *via_new_spec(struct hda_codec *codec) 122static struct via_spec *via_new_spec(struct hda_codec *codec)
124{ 123{
@@ -575,25 +574,12 @@ static const struct snd_kcontrol_new vt1708_jack_detect_ctl[] = {
575 {} /* terminator */ 574 {} /* terminator */
576}; 575};
577 576
578static void via_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *tbl) 577static void via_jack_powerstate_event(struct hda_codec *codec,
578 struct hda_jack_callback *tbl)
579{ 579{
580 set_widgets_power_state(codec); 580 set_widgets_power_state(codec);
581 snd_hda_gen_hp_automute(codec, tbl);
582} 581}
583 582
584static void via_line_automute(struct hda_codec *codec, struct hda_jack_tbl *tbl)
585{
586 set_widgets_power_state(codec);
587 snd_hda_gen_line_automute(codec, tbl);
588}
589
590static void via_jack_powerstate_event(struct hda_codec *codec, struct hda_jack_tbl *tbl)
591{
592 set_widgets_power_state(codec);
593}
594
595#define VIA_JACK_EVENT (HDA_GEN_LAST_EVENT + 1)
596
597static void via_set_jack_unsol_events(struct hda_codec *codec) 583static void via_set_jack_unsol_events(struct hda_codec *codec)
598{ 584{
599 struct via_spec *spec = codec->spec; 585 struct via_spec *spec = codec->spec;
@@ -601,25 +587,17 @@ static void via_set_jack_unsol_events(struct hda_codec *codec)
601 hda_nid_t pin; 587 hda_nid_t pin;
602 int i; 588 int i;
603 589
604 spec->gen.hp_automute_hook = via_hp_automute;
605 if (cfg->speaker_pins[0])
606 spec->gen.line_automute_hook = via_line_automute;
607
608 for (i = 0; i < cfg->line_outs; i++) { 590 for (i = 0; i < cfg->line_outs; i++) {
609 pin = cfg->line_out_pins[i]; 591 pin = cfg->line_out_pins[i];
610 if (pin && !snd_hda_jack_tbl_get(codec, pin) && 592 if (pin && is_jack_detectable(codec, pin))
611 is_jack_detectable(codec, pin))
612 snd_hda_jack_detect_enable_callback(codec, pin, 593 snd_hda_jack_detect_enable_callback(codec, pin,
613 VIA_JACK_EVENT,
614 via_jack_powerstate_event); 594 via_jack_powerstate_event);
615 } 595 }
616 596
617 for (i = 0; i < cfg->num_inputs; i++) { 597 for (i = 0; i < cfg->num_inputs; i++) {
618 pin = cfg->line_out_pins[i]; 598 pin = cfg->line_out_pins[i];
619 if (pin && !snd_hda_jack_tbl_get(codec, pin) && 599 if (pin && is_jack_detectable(codec, pin))
620 is_jack_detectable(codec, pin))
621 snd_hda_jack_detect_enable_callback(codec, pin, 600 snd_hda_jack_detect_enable_callback(codec, pin,
622 VIA_JACK_EVENT,
623 via_jack_powerstate_event); 601 via_jack_powerstate_event);
624 } 602 }
625} 603}