diff options
author | Takashi Iwai <tiwai@suse.de> | 2014-09-22 04:12:16 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2014-09-22 04:12:16 -0400 |
commit | 7639913f7298ed23a3f026ebcbb3b4e8850bcc39 (patch) | |
tree | 26f08f061535015b748a96106f4869560e3afc63 /sound/pci/hda | |
parent | 4e9c58cb1219bcbcf6e698ed6541b275048bfa88 (diff) | |
parent | f8fb117034847634bff8f02632151f7535981fa1 (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.h | 2 | ||||
-rw-r--r-- | sound/pci/hda/hda_generic.c | 23 | ||||
-rw-r--r-- | sound/pci/hda/hda_generic.h | 18 | ||||
-rw-r--r-- | sound/pci/hda/hda_jack.c | 83 | ||||
-rw-r--r-- | sound/pci/hda/hda_jack.h | 42 | ||||
-rw-r--r-- | sound/pci/hda/patch_ca0132.c | 74 | ||||
-rw-r--r-- | sound/pci/hda/patch_cirrus.c | 5 | ||||
-rw-r--r-- | sound/pci/hda/patch_conexant.c | 12 | ||||
-rw-r--r-- | sound/pci/hda/patch_hdmi.c | 18 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 41 | ||||
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 79 | ||||
-rw-r--r-- | sound/pci/hda/patch_via.c | 30 |
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 | ||
2035 | static void call_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack); | 2035 | static void call_hp_automute(struct hda_codec *codec, |
2036 | struct hda_jack_callback *jack); | ||
2036 | static int indep_hp_info(struct snd_kcontrol *kcontrol, | 2037 | static 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 */ |
3951 | void snd_hda_gen_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack) | 3952 | void 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) | |||
3968 | EXPORT_SYMBOL_GPL(snd_hda_gen_hp_automute); | 3970 | EXPORT_SYMBOL_GPL(snd_hda_gen_hp_automute); |
3969 | 3971 | ||
3970 | /* standard line-out-automute helper */ | 3972 | /* standard line-out-automute helper */ |
3971 | void snd_hda_gen_line_automute(struct hda_codec *codec, struct hda_jack_tbl *jack) | 3973 | void 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 | |||
3988 | EXPORT_SYMBOL_GPL(snd_hda_gen_line_automute); | 3991 | EXPORT_SYMBOL_GPL(snd_hda_gen_line_automute); |
3989 | 3992 | ||
3990 | /* standard mic auto-switch helper */ | 3993 | /* standard mic auto-switch helper */ |
3991 | void snd_hda_gen_mic_autoswitch(struct hda_codec *codec, struct hda_jack_tbl *jack) | 3994 | void 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 | |||
4011 | EXPORT_SYMBOL_GPL(snd_hda_gen_mic_autoswitch); | 4015 | EXPORT_SYMBOL_GPL(snd_hda_gen_mic_autoswitch); |
4012 | 4016 | ||
4013 | /* call appropriate hooks */ | 4017 | /* call appropriate hooks */ |
4014 | static void call_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack) | 4018 | static 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 | ||
4023 | static void call_line_automute(struct hda_codec *codec, | 4028 | static 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 | ||
4033 | static void call_mic_autoswitch(struct hda_codec *codec, | 4038 | static 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 */ | ||
16 | enum { | ||
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 */ |
22 | struct hda_multi_io { | 16 | struct 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 | ||
300 | int snd_hda_gen_spec_init(struct hda_gen_spec *spec); | 294 | int 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 */ |
328 | void snd_hda_gen_hp_automute(struct hda_codec *codec, | 322 | void snd_hda_gen_hp_automute(struct hda_codec *codec, |
329 | struct hda_jack_tbl *jack); | 323 | struct hda_jack_callback *jack); |
330 | void snd_hda_gen_line_automute(struct hda_codec *codec, | 324 | void snd_hda_gen_line_automute(struct hda_codec *codec, |
331 | struct hda_jack_tbl *jack); | 325 | struct hda_jack_callback *jack); |
332 | void snd_hda_gen_mic_autoswitch(struct hda_codec *codec, | 326 | void snd_hda_gen_mic_autoswitch(struct hda_codec *codec, |
333 | struct hda_jack_tbl *jack); | 327 | struct hda_jack_callback *jack); |
334 | void snd_hda_gen_update_outputs(struct hda_codec *codec); | 328 | void 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 | */ |
97 | struct hda_jack_tbl * | 97 | static struct hda_jack_tbl * |
98 | snd_hda_jack_tbl_new(struct hda_codec *codec, hda_nid_t nid) | 98 | snd_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 | } |
111 | EXPORT_SYMBOL_GPL(snd_hda_jack_tbl_new); | ||
112 | 111 | ||
113 | void snd_hda_jack_tbl_clear(struct hda_codec *codec) | 112 | void 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 | */ |
219 | int snd_hda_jack_detect_enable_callback(struct hda_codec *codec, hda_nid_t nid, | 226 | struct hda_jack_callback * |
220 | unsigned char action, | 227 | snd_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 | } |
239 | EXPORT_SYMBOL_GPL(snd_hda_jack_detect_enable_callback); | 259 | EXPORT_SYMBOL_GPL(snd_hda_jack_detect_enable_callback); |
240 | 260 | ||
241 | int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid, | 261 | int 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 | } |
246 | EXPORT_SYMBOL_GPL(snd_hda_jack_detect_enable); | 265 | EXPORT_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); | |||
498 | static void call_jack_callback(struct hda_codec *codec, | 517 | static 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 | ||
15 | struct auto_pin_cfg; | 15 | struct auto_pin_cfg; |
16 | struct hda_jack_tbl; | 16 | struct hda_jack_tbl; |
17 | struct hda_jack_callback; | ||
17 | 18 | ||
18 | typedef void (*hda_jack_callback) (struct hda_codec *, struct hda_jack_tbl *); | 19 | typedef void (*hda_jack_callback_fn) (struct hda_codec *, struct hda_jack_callback *); |
20 | |||
21 | struct 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 | ||
20 | struct hda_jack_tbl { | 28 | struct 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); | |||
43 | struct hda_jack_tbl * | 49 | struct hda_jack_tbl * |
44 | snd_hda_jack_tbl_get_from_tag(struct hda_codec *codec, unsigned char tag); | 50 | snd_hda_jack_tbl_get_from_tag(struct hda_codec *codec, unsigned char tag); |
45 | 51 | ||
46 | struct hda_jack_tbl * | ||
47 | snd_hda_jack_tbl_new(struct hda_codec *codec, hda_nid_t nid); | ||
48 | void snd_hda_jack_tbl_clear(struct hda_codec *codec); | 52 | void 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 | */ | ||
56 | static inline unsigned char | ||
57 | snd_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 | |||
67 | void snd_hda_jack_set_dirty_all(struct hda_codec *codec); | 54 | void snd_hda_jack_set_dirty_all(struct hda_codec *codec); |
68 | 55 | ||
69 | int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid, | 56 | int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid); |
70 | unsigned char action); | 57 | struct hda_jack_callback * |
71 | int snd_hda_jack_detect_enable_callback(struct hda_codec *codec, hda_nid_t nid, | 58 | snd_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 | ||
75 | int snd_hda_jack_set_gating_jack(struct hda_codec *codec, hda_nid_t gated_nid, | 61 | int 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 | ||
3231 | static void ca0132_set_dmic(struct hda_codec *codec, int enable); | 3237 | static 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 | ||
4117 | static 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 | |||
4123 | static void refresh_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir) | 4123 | static 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 | ||
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 | 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 | ||
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 | 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: | 4420 | static 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, | 4425 | static 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) | |||
4443 | static struct hda_verb ca0132_base_init_verbs[] = { | 4439 | static 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 | ||
4618 | static void ca0132_config(struct hda_codec *codec) | 4612 | static 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 | ||
986 | static void cs4210_spdif_automute(struct hda_codec *codec, | 984 | static 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 */ |
395 | static void olpc_xo_automic(struct hda_codec *codec, struct hda_jack_tbl *jack) | 396 | static 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 | ||
744 | static const struct snd_pci_quirk cxt5066_fixups[] = { | 752 | static 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 | ||
1164 | static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll); | 1164 | static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll); |
1165 | 1165 | ||
1166 | static void jack_callback(struct hda_codec *codec, struct hda_jack_tbl *jack) | 1166 | static 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 | ||
1177 | static 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 | |||
1177 | static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) | 1183 | static 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 | ||
1196 | static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res) | 1202 | static 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 */ |
270 | static void alc_update_knob_master(struct hda_codec *codec, struct hda_jack_tbl *jack) | 267 | static 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 | ||
1135 | static const struct hda_fixup alc880_fixups[] = { | 1135 | static 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 | ||
3274 | static void alc269_x101_hp_automute_hook(struct hda_codec *codec, | 3275 | static 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 | ||
3929 | static void alc_update_headset_jack_cb(struct hda_codec *codec, struct hda_jack_tbl *jack) | 3930 | static 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 | ||
4168 | static void alc283_hp_automute_hook(struct hda_codec *codec, | 4170 | static 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 | ||
4358 | static const struct hda_fixup alc269_fixups[] = { | 4360 | static 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 | ||
42 | enum { | 42 | enum { |
43 | STAC_VREF_EVENT = 8, | ||
44 | STAC_PWR_EVENT, | ||
45 | }; | ||
46 | |||
47 | enum { | ||
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 */ |
488 | static void jack_update_power(struct hda_codec *codec, | 483 | static 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 | ||
521 | static void stac_hp_automute(struct hda_codec *codec, | 513 | static 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 | |||
528 | static 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 | |||
535 | static 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 | |||
542 | static 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 | |||
4281 | static int stac_init(struct hda_codec *codec) | 4242 | static 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); |
121 | static void via_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *tbl); | ||
122 | 121 | ||
123 | static struct via_spec *via_new_spec(struct hda_codec *codec) | 122 | static 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 | ||
578 | static void via_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *tbl) | 577 | static 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 | ||
584 | static 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 | |||
590 | static 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 | |||
597 | static void via_set_jack_unsol_events(struct hda_codec *codec) | 583 | static 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 | } |