diff options
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/hda/hda_codec.c | 64 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.h | 1 | ||||
-rw-r--r-- | sound/pci/hda/hda_eld.c | 13 | ||||
-rw-r--r-- | sound/pci/hda/hda_local.h | 19 | ||||
-rw-r--r-- | sound/pci/hda/patch_cirrus.c | 23 | ||||
-rw-r--r-- | sound/pci/hda/patch_conexant.c | 1 | ||||
-rw-r--r-- | sound/pci/hda/patch_hdmi.c | 55 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 15 | ||||
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 44 | ||||
-rw-r--r-- | sound/pci/intel8x0.c | 58 |
10 files changed, 186 insertions, 107 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 916a1863af73..e44b107fdc75 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -2331,6 +2331,39 @@ int snd_hda_codec_reset(struct hda_codec *codec) | |||
2331 | return 0; | 2331 | return 0; |
2332 | } | 2332 | } |
2333 | 2333 | ||
2334 | typedef int (*map_slave_func_t)(void *, struct snd_kcontrol *); | ||
2335 | |||
2336 | /* apply the function to all matching slave ctls in the mixer list */ | ||
2337 | static int map_slaves(struct hda_codec *codec, const char * const *slaves, | ||
2338 | map_slave_func_t func, void *data) | ||
2339 | { | ||
2340 | struct hda_nid_item *items; | ||
2341 | const char * const *s; | ||
2342 | int i, err; | ||
2343 | |||
2344 | items = codec->mixers.list; | ||
2345 | for (i = 0; i < codec->mixers.used; i++) { | ||
2346 | struct snd_kcontrol *sctl = items[i].kctl; | ||
2347 | if (!sctl || !sctl->id.name || | ||
2348 | sctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER) | ||
2349 | continue; | ||
2350 | for (s = slaves; *s; s++) { | ||
2351 | if (!strcmp(sctl->id.name, *s)) { | ||
2352 | err = func(data, sctl); | ||
2353 | if (err) | ||
2354 | return err; | ||
2355 | break; | ||
2356 | } | ||
2357 | } | ||
2358 | } | ||
2359 | return 0; | ||
2360 | } | ||
2361 | |||
2362 | static int check_slave_present(void *data, struct snd_kcontrol *sctl) | ||
2363 | { | ||
2364 | return 1; | ||
2365 | } | ||
2366 | |||
2334 | /** | 2367 | /** |
2335 | * snd_hda_add_vmaster - create a virtual master control and add slaves | 2368 | * snd_hda_add_vmaster - create a virtual master control and add slaves |
2336 | * @codec: HD-audio codec | 2369 | * @codec: HD-audio codec |
@@ -2351,12 +2384,10 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name, | |||
2351 | unsigned int *tlv, const char * const *slaves) | 2384 | unsigned int *tlv, const char * const *slaves) |
2352 | { | 2385 | { |
2353 | struct snd_kcontrol *kctl; | 2386 | struct snd_kcontrol *kctl; |
2354 | const char * const *s; | ||
2355 | int err; | 2387 | int err; |
2356 | 2388 | ||
2357 | for (s = slaves; *s && !snd_hda_find_mixer_ctl(codec, *s); s++) | 2389 | err = map_slaves(codec, slaves, check_slave_present, NULL); |
2358 | ; | 2390 | if (err != 1) { |
2359 | if (!*s) { | ||
2360 | snd_printdd("No slave found for %s\n", name); | 2391 | snd_printdd("No slave found for %s\n", name); |
2361 | return 0; | 2392 | return 0; |
2362 | } | 2393 | } |
@@ -2367,23 +2398,10 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name, | |||
2367 | if (err < 0) | 2398 | if (err < 0) |
2368 | return err; | 2399 | return err; |
2369 | 2400 | ||
2370 | for (s = slaves; *s; s++) { | 2401 | err = map_slaves(codec, slaves, (map_slave_func_t)snd_ctl_add_slave, |
2371 | struct snd_kcontrol *sctl; | 2402 | kctl); |
2372 | int i = 0; | 2403 | if (err < 0) |
2373 | for (;;) { | 2404 | return err; |
2374 | sctl = _snd_hda_find_mixer_ctl(codec, *s, i); | ||
2375 | if (!sctl) { | ||
2376 | if (!i) | ||
2377 | snd_printdd("Cannot find slave %s, " | ||
2378 | "skipped\n", *s); | ||
2379 | break; | ||
2380 | } | ||
2381 | err = snd_ctl_add_slave(kctl, sctl); | ||
2382 | if (err < 0) | ||
2383 | return err; | ||
2384 | i++; | ||
2385 | } | ||
2386 | } | ||
2387 | return 0; | 2405 | return 0; |
2388 | } | 2406 | } |
2389 | EXPORT_SYMBOL_HDA(snd_hda_add_vmaster); | 2407 | EXPORT_SYMBOL_HDA(snd_hda_add_vmaster); |
@@ -4752,6 +4770,7 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec, | |||
4752 | memset(sequences_hp, 0, sizeof(sequences_hp)); | 4770 | memset(sequences_hp, 0, sizeof(sequences_hp)); |
4753 | assoc_line_out = 0; | 4771 | assoc_line_out = 0; |
4754 | 4772 | ||
4773 | codec->ignore_misc_bit = true; | ||
4755 | end_nid = codec->start_nid + codec->num_nodes; | 4774 | end_nid = codec->start_nid + codec->num_nodes; |
4756 | for (nid = codec->start_nid; nid < end_nid; nid++) { | 4775 | for (nid = codec->start_nid; nid < end_nid; nid++) { |
4757 | unsigned int wid_caps = get_wcaps(codec, nid); | 4776 | unsigned int wid_caps = get_wcaps(codec, nid); |
@@ -4767,6 +4786,9 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec, | |||
4767 | continue; | 4786 | continue; |
4768 | 4787 | ||
4769 | def_conf = snd_hda_codec_get_pincfg(codec, nid); | 4788 | def_conf = snd_hda_codec_get_pincfg(codec, nid); |
4789 | if (!(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) & | ||
4790 | AC_DEFCFG_MISC_NO_PRESENCE)) | ||
4791 | codec->ignore_misc_bit = false; | ||
4770 | conn = get_defcfg_connect(def_conf); | 4792 | conn = get_defcfg_connect(def_conf); |
4771 | if (conn == AC_JACK_PORT_NONE) | 4793 | if (conn == AC_JACK_PORT_NONE) |
4772 | continue; | 4794 | continue; |
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 755f2b0f9d8e..564471169cae 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
@@ -854,6 +854,7 @@ struct hda_codec { | |||
854 | unsigned int no_sticky_stream:1; /* no sticky-PCM stream assignment */ | 854 | unsigned int no_sticky_stream:1; /* no sticky-PCM stream assignment */ |
855 | unsigned int pins_shutup:1; /* pins are shut up */ | 855 | unsigned int pins_shutup:1; /* pins are shut up */ |
856 | unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */ | 856 | unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */ |
857 | unsigned int ignore_misc_bit:1; /* ignore MISC_NO_PRESENCE bit */ | ||
857 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 858 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
858 | unsigned int power_on :1; /* current (global) power-state */ | 859 | unsigned int power_on :1; /* current (global) power-state */ |
859 | unsigned int power_transition :1; /* power-state in transition */ | 860 | unsigned int power_transition :1; /* power-state in transition */ |
diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c index 1c8ddf547a2d..7ae7578bdcc0 100644 --- a/sound/pci/hda/hda_eld.c +++ b/sound/pci/hda/hda_eld.c | |||
@@ -297,10 +297,18 @@ static int hdmi_update_eld(struct hdmi_eld *e, | |||
297 | buf + ELD_FIXED_BYTES + mnl + 3 * i); | 297 | buf + ELD_FIXED_BYTES + mnl + 3 * i); |
298 | } | 298 | } |
299 | 299 | ||
300 | /* | ||
301 | * HDMI sink's ELD info cannot always be retrieved for now, e.g. | ||
302 | * in console or for audio devices. Assume the highest speakers | ||
303 | * configuration, to _not_ prohibit multi-channel audio playback. | ||
304 | */ | ||
305 | if (!e->spk_alloc) | ||
306 | e->spk_alloc = 0xffff; | ||
307 | |||
308 | e->eld_valid = true; | ||
300 | return 0; | 309 | return 0; |
301 | 310 | ||
302 | out_fail: | 311 | out_fail: |
303 | e->eld_ver = 0; | ||
304 | return -EINVAL; | 312 | return -EINVAL; |
305 | } | 313 | } |
306 | 314 | ||
@@ -323,9 +331,6 @@ int snd_hdmi_get_eld(struct hdmi_eld *eld, | |||
323 | * ELD is valid, actual eld_size is assigned in hdmi_update_eld() | 331 | * ELD is valid, actual eld_size is assigned in hdmi_update_eld() |
324 | */ | 332 | */ |
325 | 333 | ||
326 | if (!eld->eld_valid) | ||
327 | return -ENOENT; | ||
328 | |||
329 | size = snd_hdmi_get_eld_size(codec, nid); | 334 | size = snd_hdmi_get_eld_size(codec, nid); |
330 | if (size == 0) { | 335 | if (size == 0) { |
331 | /* wfg: workaround for ASUS P5E-VM HDMI board */ | 336 | /* wfg: workaround for ASUS P5E-VM HDMI board */ |
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index dcbea0da0fa2..618ddad17236 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h | |||
@@ -510,13 +510,15 @@ int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid); | |||
510 | 510 | ||
511 | static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) | 511 | static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) |
512 | { | 512 | { |
513 | return (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT) && | 513 | if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT)) |
514 | /* disable MISC_NO_PRESENCE check because it may break too | 514 | return false; |
515 | * many devices | 515 | if (!codec->ignore_misc_bit && |
516 | */ | 516 | (get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) & |
517 | /*(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid) & | 517 | AC_DEFCFG_MISC_NO_PRESENCE)) |
518 | AC_DEFCFG_MISC_NO_PRESENCE)) &&*/ | 518 | return false; |
519 | (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP); | 519 | if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP)) |
520 | return false; | ||
521 | return true; | ||
520 | } | 522 | } |
521 | 523 | ||
522 | /* flags for hda_nid_item */ | 524 | /* flags for hda_nid_item */ |
@@ -651,6 +653,9 @@ struct hdmi_eld { | |||
651 | int spk_alloc; | 653 | int spk_alloc; |
652 | int sad_count; | 654 | int sad_count; |
653 | struct cea_sad sad[ELD_MAX_SAD]; | 655 | struct cea_sad sad[ELD_MAX_SAD]; |
656 | /* | ||
657 | * all fields above eld_buffer will be cleared before updating ELD | ||
658 | */ | ||
654 | char eld_buffer[ELD_MAX_SIZE]; | 659 | char eld_buffer[ELD_MAX_SIZE]; |
655 | #ifdef CONFIG_PROC_FS | 660 | #ifdef CONFIG_PROC_FS |
656 | struct snd_info_entry *proc_entry; | 661 | struct snd_info_entry *proc_entry; |
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index 2a2d8645ba09..2fbab8e29576 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c | |||
@@ -237,6 +237,15 @@ static int cs_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
237 | return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout); | 237 | return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout); |
238 | } | 238 | } |
239 | 239 | ||
240 | static void cs_update_input_select(struct hda_codec *codec) | ||
241 | { | ||
242 | struct cs_spec *spec = codec->spec; | ||
243 | if (spec->cur_adc) | ||
244 | snd_hda_codec_write(codec, spec->cur_adc, 0, | ||
245 | AC_VERB_SET_CONNECT_SEL, | ||
246 | spec->adc_idx[spec->cur_input]); | ||
247 | } | ||
248 | |||
240 | /* | 249 | /* |
241 | * Analog capture | 250 | * Analog capture |
242 | */ | 251 | */ |
@@ -250,6 +259,7 @@ static int cs_capture_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
250 | spec->cur_adc = spec->adc_nid[spec->cur_input]; | 259 | spec->cur_adc = spec->adc_nid[spec->cur_input]; |
251 | spec->cur_adc_stream_tag = stream_tag; | 260 | spec->cur_adc_stream_tag = stream_tag; |
252 | spec->cur_adc_format = format; | 261 | spec->cur_adc_format = format; |
262 | cs_update_input_select(codec); | ||
253 | snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format); | 263 | snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format); |
254 | return 0; | 264 | return 0; |
255 | } | 265 | } |
@@ -689,10 +699,8 @@ static int change_cur_input(struct hda_codec *codec, unsigned int idx, | |||
689 | spec->cur_adc_stream_tag, 0, | 699 | spec->cur_adc_stream_tag, 0, |
690 | spec->cur_adc_format); | 700 | spec->cur_adc_format); |
691 | } | 701 | } |
692 | snd_hda_codec_write(codec, spec->cur_adc, 0, | ||
693 | AC_VERB_SET_CONNECT_SEL, | ||
694 | spec->adc_idx[idx]); | ||
695 | spec->cur_input = idx; | 702 | spec->cur_input = idx; |
703 | cs_update_input_select(codec); | ||
696 | return 1; | 704 | return 1; |
697 | } | 705 | } |
698 | 706 | ||
@@ -973,10 +981,7 @@ static void cs_automic(struct hda_codec *codec) | |||
973 | } else { | 981 | } else { |
974 | spec->cur_input = spec->last_input; | 982 | spec->cur_input = spec->last_input; |
975 | } | 983 | } |
976 | 984 | cs_update_input_select(codec); | |
977 | snd_hda_codec_write_cache(codec, spec->cur_adc, 0, | ||
978 | AC_VERB_SET_CONNECT_SEL, | ||
979 | spec->adc_idx[spec->cur_input]); | ||
980 | } else { | 985 | } else { |
981 | if (present) | 986 | if (present) |
982 | change_cur_input(codec, spec->automic_idx, 0); | 987 | change_cur_input(codec, spec->automic_idx, 0); |
@@ -1073,9 +1078,7 @@ static void init_input(struct hda_codec *codec) | |||
1073 | cs_automic(codec); | 1078 | cs_automic(codec); |
1074 | else { | 1079 | else { |
1075 | spec->cur_adc = spec->adc_nid[spec->cur_input]; | 1080 | spec->cur_adc = spec->adc_nid[spec->cur_input]; |
1076 | snd_hda_codec_write(codec, spec->cur_adc, 0, | 1081 | cs_update_input_select(codec); |
1077 | AC_VERB_SET_CONNECT_SEL, | ||
1078 | spec->adc_idx[spec->cur_input]); | ||
1079 | } | 1082 | } |
1080 | } else { | 1083 | } else { |
1081 | change_cur_input(codec, spec->cur_input, 1); | 1084 | change_cur_input(codec, spec->cur_input, 1); |
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 5e706e4d1737..0de21193a2b0 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -3062,7 +3062,6 @@ static const struct snd_pci_quirk cxt5066_cfg_tbl[] = { | |||
3062 | SND_PCI_QUIRK(0x1043, 0x1993, "Asus U50F", CXT5066_ASUS), | 3062 | SND_PCI_QUIRK(0x1043, 0x1993, "Asus U50F", CXT5066_ASUS), |
3063 | SND_PCI_QUIRK(0x1179, 0xff1e, "Toshiba Satellite C650D", CXT5066_IDEAPAD), | 3063 | SND_PCI_QUIRK(0x1179, 0xff1e, "Toshiba Satellite C650D", CXT5066_IDEAPAD), |
3064 | SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5), | 3064 | SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5), |
3065 | SND_PCI_QUIRK(0x1179, 0xffe0, "Toshiba Satellite Pro T130-15F", CXT5066_OLPC_XO_1_5), | ||
3066 | SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board", | 3065 | SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board", |
3067 | CXT5066_LAPTOP), | 3066 | CXT5066_LAPTOP), |
3068 | SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5), | 3067 | SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5), |
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 81b7b791b3c3..9850c5b481ea 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c | |||
@@ -65,7 +65,10 @@ struct hdmi_spec_per_pin { | |||
65 | hda_nid_t pin_nid; | 65 | hda_nid_t pin_nid; |
66 | int num_mux_nids; | 66 | int num_mux_nids; |
67 | hda_nid_t mux_nids[HDA_MAX_CONNECTIONS]; | 67 | hda_nid_t mux_nids[HDA_MAX_CONNECTIONS]; |
68 | |||
69 | struct hda_codec *codec; | ||
68 | struct hdmi_eld sink_eld; | 70 | struct hdmi_eld sink_eld; |
71 | struct delayed_work work; | ||
69 | }; | 72 | }; |
70 | 73 | ||
71 | struct hdmi_spec { | 74 | struct hdmi_spec { |
@@ -745,8 +748,7 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, int pin_idx, | |||
745 | * Unsolicited events | 748 | * Unsolicited events |
746 | */ | 749 | */ |
747 | 750 | ||
748 | static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid, | 751 | static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, bool retry); |
749 | struct hdmi_eld *eld); | ||
750 | 752 | ||
751 | static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) | 753 | static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) |
752 | { | 754 | { |
@@ -755,7 +757,6 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) | |||
755 | int pd = !!(res & AC_UNSOL_RES_PD); | 757 | int pd = !!(res & AC_UNSOL_RES_PD); |
756 | int eldv = !!(res & AC_UNSOL_RES_ELDV); | 758 | int eldv = !!(res & AC_UNSOL_RES_ELDV); |
757 | int pin_idx; | 759 | int pin_idx; |
758 | struct hdmi_eld *eld; | ||
759 | 760 | ||
760 | printk(KERN_INFO | 761 | printk(KERN_INFO |
761 | "HDMI hot plug event: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n", | 762 | "HDMI hot plug event: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n", |
@@ -764,17 +765,8 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) | |||
764 | pin_idx = pin_nid_to_pin_index(spec, pin_nid); | 765 | pin_idx = pin_nid_to_pin_index(spec, pin_nid); |
765 | if (pin_idx < 0) | 766 | if (pin_idx < 0) |
766 | return; | 767 | return; |
767 | eld = &spec->pins[pin_idx].sink_eld; | ||
768 | |||
769 | hdmi_present_sense(codec, pin_nid, eld); | ||
770 | 768 | ||
771 | /* | 769 | hdmi_present_sense(&spec->pins[pin_idx], true); |
772 | * HDMI sink's ELD info cannot always be retrieved for now, e.g. | ||
773 | * in console or for audio devices. Assume the highest speakers | ||
774 | * configuration, to _not_ prohibit multi-channel audio playback. | ||
775 | */ | ||
776 | if (!eld->spk_alloc) | ||
777 | eld->spk_alloc = 0xffff; | ||
778 | } | 770 | } |
779 | 771 | ||
780 | static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res) | 772 | static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res) |
@@ -968,9 +960,11 @@ static int hdmi_read_pin_conn(struct hda_codec *codec, int pin_idx) | |||
968 | return 0; | 960 | return 0; |
969 | } | 961 | } |
970 | 962 | ||
971 | static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid, | 963 | static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, bool retry) |
972 | struct hdmi_eld *eld) | ||
973 | { | 964 | { |
965 | struct hda_codec *codec = per_pin->codec; | ||
966 | struct hdmi_eld *eld = &per_pin->sink_eld; | ||
967 | hda_nid_t pin_nid = per_pin->pin_nid; | ||
974 | /* | 968 | /* |
975 | * Always execute a GetPinSense verb here, even when called from | 969 | * Always execute a GetPinSense verb here, even when called from |
976 | * hdmi_intrinsic_event; for some NVIDIA HW, the unsolicited | 970 | * hdmi_intrinsic_event; for some NVIDIA HW, the unsolicited |
@@ -980,26 +974,39 @@ static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid, | |||
980 | * the unsolicited response to avoid custom WARs. | 974 | * the unsolicited response to avoid custom WARs. |
981 | */ | 975 | */ |
982 | int present = snd_hda_pin_sense(codec, pin_nid); | 976 | int present = snd_hda_pin_sense(codec, pin_nid); |
977 | bool eld_valid = false; | ||
983 | 978 | ||
984 | memset(eld, 0, sizeof(*eld)); | 979 | memset(eld, 0, offsetof(struct hdmi_eld, eld_buffer)); |
985 | 980 | ||
986 | eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE); | 981 | eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE); |
987 | if (eld->monitor_present) | 982 | if (eld->monitor_present) |
988 | eld->eld_valid = !!(present & AC_PINSENSE_ELDV); | 983 | eld_valid = !!(present & AC_PINSENSE_ELDV); |
989 | else | ||
990 | eld->eld_valid = 0; | ||
991 | 984 | ||
992 | printk(KERN_INFO | 985 | printk(KERN_INFO |
993 | "HDMI status: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n", | 986 | "HDMI status: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n", |
994 | codec->addr, pin_nid, eld->monitor_present, eld->eld_valid); | 987 | codec->addr, pin_nid, eld->monitor_present, eld_valid); |
995 | 988 | ||
996 | if (eld->eld_valid) | 989 | if (eld_valid) { |
997 | if (!snd_hdmi_get_eld(eld, codec, pin_nid)) | 990 | if (!snd_hdmi_get_eld(eld, codec, pin_nid)) |
998 | snd_hdmi_show_eld(eld); | 991 | snd_hdmi_show_eld(eld); |
992 | else if (retry) { | ||
993 | queue_delayed_work(codec->bus->workq, | ||
994 | &per_pin->work, | ||
995 | msecs_to_jiffies(300)); | ||
996 | } | ||
997 | } | ||
999 | 998 | ||
1000 | snd_hda_input_jack_report(codec, pin_nid); | 999 | snd_hda_input_jack_report(codec, pin_nid); |
1001 | } | 1000 | } |
1002 | 1001 | ||
1002 | static void hdmi_repoll_eld(struct work_struct *work) | ||
1003 | { | ||
1004 | struct hdmi_spec_per_pin *per_pin = | ||
1005 | container_of(to_delayed_work(work), struct hdmi_spec_per_pin, work); | ||
1006 | |||
1007 | hdmi_present_sense(per_pin, false); | ||
1008 | } | ||
1009 | |||
1003 | static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid) | 1010 | static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid) |
1004 | { | 1011 | { |
1005 | struct hdmi_spec *spec = codec->spec; | 1012 | struct hdmi_spec *spec = codec->spec; |
@@ -1228,7 +1235,7 @@ static int generic_hdmi_build_jack(struct hda_codec *codec, int pin_idx) | |||
1228 | if (err < 0) | 1235 | if (err < 0) |
1229 | return err; | 1236 | return err; |
1230 | 1237 | ||
1231 | hdmi_present_sense(codec, per_pin->pin_nid, &per_pin->sink_eld); | 1238 | hdmi_present_sense(per_pin, false); |
1232 | return 0; | 1239 | return 0; |
1233 | } | 1240 | } |
1234 | 1241 | ||
@@ -1279,6 +1286,8 @@ static int generic_hdmi_init(struct hda_codec *codec) | |||
1279 | AC_VERB_SET_UNSOLICITED_ENABLE, | 1286 | AC_VERB_SET_UNSOLICITED_ENABLE, |
1280 | AC_USRSP_EN | pin_nid); | 1287 | AC_USRSP_EN | pin_nid); |
1281 | 1288 | ||
1289 | per_pin->codec = codec; | ||
1290 | INIT_DELAYED_WORK(&per_pin->work, hdmi_repoll_eld); | ||
1282 | snd_hda_eld_proc_new(codec, eld, pin_idx); | 1291 | snd_hda_eld_proc_new(codec, eld, pin_idx); |
1283 | } | 1292 | } |
1284 | return 0; | 1293 | return 0; |
@@ -1293,10 +1302,12 @@ static void generic_hdmi_free(struct hda_codec *codec) | |||
1293 | struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; | 1302 | struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; |
1294 | struct hdmi_eld *eld = &per_pin->sink_eld; | 1303 | struct hdmi_eld *eld = &per_pin->sink_eld; |
1295 | 1304 | ||
1305 | cancel_delayed_work(&per_pin->work); | ||
1296 | snd_hda_eld_proc_free(codec, eld); | 1306 | snd_hda_eld_proc_free(codec, eld); |
1297 | } | 1307 | } |
1298 | snd_hda_input_jack_free(codec); | 1308 | snd_hda_input_jack_free(codec); |
1299 | 1309 | ||
1310 | flush_workqueue(codec->bus->workq); | ||
1300 | kfree(spec); | 1311 | kfree(spec); |
1301 | } | 1312 | } |
1302 | 1313 | ||
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index a24e068a021b..336d14eb72af 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -284,7 +284,7 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, | |||
284 | struct alc_spec *spec = codec->spec; | 284 | struct alc_spec *spec = codec->spec; |
285 | const struct hda_input_mux *imux; | 285 | const struct hda_input_mux *imux; |
286 | unsigned int mux_idx; | 286 | unsigned int mux_idx; |
287 | int i, type; | 287 | int i, type, num_conns; |
288 | hda_nid_t nid; | 288 | hda_nid_t nid; |
289 | 289 | ||
290 | mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; | 290 | mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; |
@@ -307,16 +307,17 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, | |||
307 | spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx]; | 307 | spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx]; |
308 | 308 | ||
309 | /* no selection? */ | 309 | /* no selection? */ |
310 | if (snd_hda_get_conn_list(codec, nid, NULL) <= 1) | 310 | num_conns = snd_hda_get_conn_list(codec, nid, NULL); |
311 | if (num_conns <= 1) | ||
311 | return 1; | 312 | return 1; |
312 | 313 | ||
313 | type = get_wcaps_type(get_wcaps(codec, nid)); | 314 | type = get_wcaps_type(get_wcaps(codec, nid)); |
314 | if (type == AC_WID_AUD_MIX) { | 315 | if (type == AC_WID_AUD_MIX) { |
315 | /* Matrix-mixer style (e.g. ALC882) */ | 316 | /* Matrix-mixer style (e.g. ALC882) */ |
316 | for (i = 0; i < imux->num_items; i++) { | 317 | int active = imux->items[idx].index; |
317 | unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; | 318 | for (i = 0; i < num_conns; i++) { |
318 | snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, | 319 | unsigned int v = (i == active) ? 0 : HDA_AMP_MUTE; |
319 | imux->items[i].index, | 320 | snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, i, |
320 | HDA_AMP_MUTE, v); | 321 | HDA_AMP_MUTE, v); |
321 | } | 322 | } |
322 | } else { | 323 | } else { |
@@ -1451,7 +1452,7 @@ static void alc_apply_fixup(struct hda_codec *codec, int action) | |||
1451 | switch (fix->type) { | 1452 | switch (fix->type) { |
1452 | case ALC_FIXUP_SKU: | 1453 | case ALC_FIXUP_SKU: |
1453 | if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku) | 1454 | if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku) |
1454 | break;; | 1455 | break; |
1455 | snd_printdd(KERN_INFO "hda_codec: %s: " | 1456 | snd_printdd(KERN_INFO "hda_codec: %s: " |
1456 | "Apply sku override for %s\n", | 1457 | "Apply sku override for %s\n", |
1457 | codec->chip_name, modelname); | 1458 | codec->chip_name, modelname); |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 4e715fefebef..470f6f286e81 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -95,6 +95,7 @@ enum { | |||
95 | STAC_92HD83XXX_REF, | 95 | STAC_92HD83XXX_REF, |
96 | STAC_92HD83XXX_PWR_REF, | 96 | STAC_92HD83XXX_PWR_REF, |
97 | STAC_DELL_S14, | 97 | STAC_DELL_S14, |
98 | STAC_DELL_VOSTRO_3500, | ||
98 | STAC_92HD83XXX_HP, | 99 | STAC_92HD83XXX_HP, |
99 | STAC_92HD83XXX_HP_cNB11_INTQUAD, | 100 | STAC_92HD83XXX_HP_cNB11_INTQUAD, |
100 | STAC_HP_DV7_4000, | 101 | STAC_HP_DV7_4000, |
@@ -226,7 +227,6 @@ struct sigmatel_spec { | |||
226 | 227 | ||
227 | /* power management */ | 228 | /* power management */ |
228 | unsigned int num_pwrs; | 229 | unsigned int num_pwrs; |
229 | const unsigned int *pwr_mapping; | ||
230 | const hda_nid_t *pwr_nids; | 230 | const hda_nid_t *pwr_nids; |
231 | const hda_nid_t *dac_list; | 231 | const hda_nid_t *dac_list; |
232 | 232 | ||
@@ -373,18 +373,15 @@ static const unsigned long stac92hd73xx_capvols[] = { | |||
373 | 373 | ||
374 | #define STAC92HD83_DAC_COUNT 3 | 374 | #define STAC92HD83_DAC_COUNT 3 |
375 | 375 | ||
376 | static const hda_nid_t stac92hd83xxx_pwr_nids[4] = { | 376 | static const hda_nid_t stac92hd83xxx_pwr_nids[7] = { |
377 | 0xa, 0xb, 0xd, 0xe, | 377 | 0x0a, 0x0b, 0x0c, 0xd, 0x0e, |
378 | 0x0f, 0x10 | ||
378 | }; | 379 | }; |
379 | 380 | ||
380 | static const hda_nid_t stac92hd83xxx_slave_dig_outs[2] = { | 381 | static const hda_nid_t stac92hd83xxx_slave_dig_outs[2] = { |
381 | 0x1e, 0, | 382 | 0x1e, 0, |
382 | }; | 383 | }; |
383 | 384 | ||
384 | static const unsigned int stac92hd83xxx_pwr_mapping[4] = { | ||
385 | 0x03, 0x0c, 0x20, 0x40, | ||
386 | }; | ||
387 | |||
388 | static const hda_nid_t stac92hd83xxx_dmic_nids[] = { | 385 | static const hda_nid_t stac92hd83xxx_dmic_nids[] = { |
389 | 0x11, 0x20, | 386 | 0x11, 0x20, |
390 | }; | 387 | }; |
@@ -1659,6 +1656,12 @@ static const unsigned int dell_s14_pin_configs[10] = { | |||
1659 | 0x40f000f0, 0x40f000f0, | 1656 | 0x40f000f0, 0x40f000f0, |
1660 | }; | 1657 | }; |
1661 | 1658 | ||
1659 | static const unsigned int dell_vostro_3500_pin_configs[10] = { | ||
1660 | 0x02a11020, 0x0221101f, 0x400000f0, 0x90170110, | ||
1661 | 0x400000f1, 0x400000f2, 0x400000f3, 0x90a60160, | ||
1662 | 0x400000f4, 0x400000f5, | ||
1663 | }; | ||
1664 | |||
1662 | static const unsigned int hp_dv7_4000_pin_configs[10] = { | 1665 | static const unsigned int hp_dv7_4000_pin_configs[10] = { |
1663 | 0x03a12050, 0x0321201f, 0x40f000f0, 0x90170110, | 1666 | 0x03a12050, 0x0321201f, 0x40f000f0, 0x90170110, |
1664 | 0x40f000f0, 0x40f000f0, 0x90170110, 0xd5a30140, | 1667 | 0x40f000f0, 0x40f000f0, 0x90170110, 0xd5a30140, |
@@ -1675,6 +1678,7 @@ static const unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = { | |||
1675 | [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs, | 1678 | [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs, |
1676 | [STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs, | 1679 | [STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs, |
1677 | [STAC_DELL_S14] = dell_s14_pin_configs, | 1680 | [STAC_DELL_S14] = dell_s14_pin_configs, |
1681 | [STAC_DELL_VOSTRO_3500] = dell_vostro_3500_pin_configs, | ||
1678 | [STAC_92HD83XXX_HP_cNB11_INTQUAD] = hp_cNB11_intquad_pin_configs, | 1682 | [STAC_92HD83XXX_HP_cNB11_INTQUAD] = hp_cNB11_intquad_pin_configs, |
1679 | [STAC_HP_DV7_4000] = hp_dv7_4000_pin_configs, | 1683 | [STAC_HP_DV7_4000] = hp_dv7_4000_pin_configs, |
1680 | }; | 1684 | }; |
@@ -1684,6 +1688,7 @@ static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = { | |||
1684 | [STAC_92HD83XXX_REF] = "ref", | 1688 | [STAC_92HD83XXX_REF] = "ref", |
1685 | [STAC_92HD83XXX_PWR_REF] = "mic-ref", | 1689 | [STAC_92HD83XXX_PWR_REF] = "mic-ref", |
1686 | [STAC_DELL_S14] = "dell-s14", | 1690 | [STAC_DELL_S14] = "dell-s14", |
1691 | [STAC_DELL_VOSTRO_3500] = "dell-vostro-3500", | ||
1687 | [STAC_92HD83XXX_HP] = "hp", | 1692 | [STAC_92HD83XXX_HP] = "hp", |
1688 | [STAC_92HD83XXX_HP_cNB11_INTQUAD] = "hp_cNB11_intquad", | 1693 | [STAC_92HD83XXX_HP_cNB11_INTQUAD] = "hp_cNB11_intquad", |
1689 | [STAC_HP_DV7_4000] = "hp-dv7-4000", | 1694 | [STAC_HP_DV7_4000] = "hp-dv7-4000", |
@@ -1697,6 +1702,8 @@ static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { | |||
1697 | "DFI LanParty", STAC_92HD83XXX_REF), | 1702 | "DFI LanParty", STAC_92HD83XXX_REF), |
1698 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ba, | 1703 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ba, |
1699 | "unknown Dell", STAC_DELL_S14), | 1704 | "unknown Dell", STAC_DELL_S14), |
1705 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x1028, | ||
1706 | "Dell Vostro 3500", STAC_DELL_VOSTRO_3500), | ||
1700 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x3600, | 1707 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x3600, |
1701 | "HP", STAC_92HD83XXX_HP), | 1708 | "HP", STAC_92HD83XXX_HP), |
1702 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1656, | 1709 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1656, |
@@ -4459,8 +4466,12 @@ static int stac92xx_init(struct hda_codec *codec) | |||
4459 | stac_toggle_power_map(codec, nid, 1); | 4466 | stac_toggle_power_map(codec, nid, 1); |
4460 | continue; | 4467 | continue; |
4461 | } | 4468 | } |
4462 | if (enable_pin_detect(codec, nid, STAC_PWR_EVENT)) | 4469 | if (enable_pin_detect(codec, nid, STAC_PWR_EVENT)) { |
4463 | stac_issue_unsol_event(codec, nid); | 4470 | stac_issue_unsol_event(codec, nid); |
4471 | continue; | ||
4472 | } | ||
4473 | /* none of the above, turn the port OFF */ | ||
4474 | stac_toggle_power_map(codec, nid, 0); | ||
4464 | } | 4475 | } |
4465 | 4476 | ||
4466 | /* sync mute LED */ | 4477 | /* sync mute LED */ |
@@ -4716,11 +4727,7 @@ static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid, | |||
4716 | if (idx >= spec->num_pwrs) | 4727 | if (idx >= spec->num_pwrs) |
4717 | return; | 4728 | return; |
4718 | 4729 | ||
4719 | /* several codecs have two power down bits */ | 4730 | idx = 1 << idx; |
4720 | if (spec->pwr_mapping) | ||
4721 | idx = spec->pwr_mapping[idx]; | ||
4722 | else | ||
4723 | idx = 1 << idx; | ||
4724 | 4731 | ||
4725 | val = snd_hda_codec_read(codec, codec->afg, 0, 0x0fec, 0x0) & 0xff; | 4732 | val = snd_hda_codec_read(codec, codec->afg, 0, 0x0fec, 0x0) & 0xff; |
4726 | if (enable) | 4733 | if (enable) |
@@ -5618,9 +5625,6 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) | |||
5618 | snd_hda_codec_set_pincfg(codec, 0xf, 0x2181205e); | 5625 | snd_hda_codec_set_pincfg(codec, 0xf, 0x2181205e); |
5619 | } | 5626 | } |
5620 | 5627 | ||
5621 | /* reset pin power-down; Windows may leave these bits after reboot */ | ||
5622 | snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7EC, 0); | ||
5623 | snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7ED, 0); | ||
5624 | codec->no_trigger_sense = 1; | 5628 | codec->no_trigger_sense = 1; |
5625 | codec->spec = spec; | 5629 | codec->spec = spec; |
5626 | 5630 | ||
@@ -5630,7 +5634,6 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) | |||
5630 | codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs; | 5634 | codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs; |
5631 | spec->digbeep_nid = 0x21; | 5635 | spec->digbeep_nid = 0x21; |
5632 | spec->pwr_nids = stac92hd83xxx_pwr_nids; | 5636 | spec->pwr_nids = stac92hd83xxx_pwr_nids; |
5633 | spec->pwr_mapping = stac92hd83xxx_pwr_mapping; | ||
5634 | spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids); | 5637 | spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids); |
5635 | spec->multiout.dac_nids = spec->dac_nids; | 5638 | spec->multiout.dac_nids = spec->dac_nids; |
5636 | spec->init = stac92hd83xxx_core_init; | 5639 | spec->init = stac92hd83xxx_core_init; |
@@ -5647,9 +5650,6 @@ again: | |||
5647 | stac92xx_set_config_regs(codec, | 5650 | stac92xx_set_config_regs(codec, |
5648 | stac92hd83xxx_brd_tbl[spec->board_config]); | 5651 | stac92hd83xxx_brd_tbl[spec->board_config]); |
5649 | 5652 | ||
5650 | if (spec->board_config != STAC_92HD83XXX_PWR_REF) | ||
5651 | spec->num_pwrs = 0; | ||
5652 | |||
5653 | codec->patch_ops = stac92xx_patch_ops; | 5653 | codec->patch_ops = stac92xx_patch_ops; |
5654 | 5654 | ||
5655 | if (find_mute_led_gpio(codec, 0)) | 5655 | if (find_mute_led_gpio(codec, 0)) |
@@ -5858,8 +5858,6 @@ again: | |||
5858 | (codec->revision_id & 0xf) == 1) | 5858 | (codec->revision_id & 0xf) == 1) |
5859 | spec->stream_delay = 40; /* 40 milliseconds */ | 5859 | spec->stream_delay = 40; /* 40 milliseconds */ |
5860 | 5860 | ||
5861 | /* no output amps */ | ||
5862 | spec->num_pwrs = 0; | ||
5863 | /* disable VSW */ | 5861 | /* disable VSW */ |
5864 | spec->init = stac92hd71bxx_core_init; | 5862 | spec->init = stac92hd71bxx_core_init; |
5865 | unmute_init++; | 5863 | unmute_init++; |
@@ -5874,8 +5872,6 @@ again: | |||
5874 | if ((codec->revision_id & 0xf) == 1) | 5872 | if ((codec->revision_id & 0xf) == 1) |
5875 | spec->stream_delay = 40; /* 40 milliseconds */ | 5873 | spec->stream_delay = 40; /* 40 milliseconds */ |
5876 | 5874 | ||
5877 | /* no output amps */ | ||
5878 | spec->num_pwrs = 0; | ||
5879 | /* fallthru */ | 5875 | /* fallthru */ |
5880 | default: | 5876 | default: |
5881 | spec->init = stac92hd71bxx_core_init; | 5877 | spec->init = stac92hd71bxx_core_init; |
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 29e312597f20..11718b49b2e2 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c | |||
@@ -1077,6 +1077,13 @@ static snd_pcm_uframes_t snd_intel8x0_pcm_pointer(struct snd_pcm_substream *subs | |||
1077 | } | 1077 | } |
1078 | if (civ != igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV)) | 1078 | if (civ != igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV)) |
1079 | continue; | 1079 | continue; |
1080 | |||
1081 | /* IO read operation is very expensive inside virtual machine | ||
1082 | * as it is emulated. The probability that subsequent PICB read | ||
1083 | * will return different result is high enough to loop till | ||
1084 | * timeout here. | ||
1085 | * Same CIV is strict enough condition to be sure that PICB | ||
1086 | * is valid inside VM on emulated card. */ | ||
1080 | if (chip->inside_vm) | 1087 | if (chip->inside_vm) |
1081 | break; | 1088 | break; |
1082 | if (ptr1 == igetword(chip, ichdev->reg_offset + ichdev->roff_picb)) | 1089 | if (ptr1 == igetword(chip, ichdev->reg_offset + ichdev->roff_picb)) |
@@ -2930,6 +2937,45 @@ static unsigned int sis_codec_bits[3] = { | |||
2930 | ICH_PCR, ICH_SCR, ICH_SIS_TCR | 2937 | ICH_PCR, ICH_SCR, ICH_SIS_TCR |
2931 | }; | 2938 | }; |
2932 | 2939 | ||
2940 | static int __devinit snd_intel8x0_inside_vm(struct pci_dev *pci) | ||
2941 | { | ||
2942 | int result = inside_vm; | ||
2943 | char *msg = NULL; | ||
2944 | |||
2945 | /* check module parameter first (override detection) */ | ||
2946 | if (result >= 0) { | ||
2947 | msg = result ? "enable (forced) VM" : "disable (forced) VM"; | ||
2948 | goto fini; | ||
2949 | } | ||
2950 | |||
2951 | /* detect KVM and Parallels virtual environments */ | ||
2952 | result = kvm_para_available(); | ||
2953 | #ifdef X86_FEATURE_HYPERVISOR | ||
2954 | result = result || boot_cpu_has(X86_FEATURE_HYPERVISOR); | ||
2955 | #endif | ||
2956 | if (!result) | ||
2957 | goto fini; | ||
2958 | |||
2959 | /* check for known (emulated) devices */ | ||
2960 | if (pci->subsystem_vendor == 0x1af4 && | ||
2961 | pci->subsystem_device == 0x1100) { | ||
2962 | /* KVM emulated sound, PCI SSID: 1af4:1100 */ | ||
2963 | msg = "enable KVM"; | ||
2964 | } else if (pci->subsystem_vendor == 0x1ab8) { | ||
2965 | /* Parallels VM emulated sound, PCI SSID: 1ab8:xxxx */ | ||
2966 | msg = "enable Parallels VM"; | ||
2967 | } else { | ||
2968 | msg = "disable (unknown or VT-d) VM"; | ||
2969 | result = 0; | ||
2970 | } | ||
2971 | |||
2972 | fini: | ||
2973 | if (msg != NULL) | ||
2974 | printk(KERN_INFO "intel8x0: %s optimization\n", msg); | ||
2975 | |||
2976 | return result; | ||
2977 | } | ||
2978 | |||
2933 | static int __devinit snd_intel8x0_create(struct snd_card *card, | 2979 | static int __devinit snd_intel8x0_create(struct snd_card *card, |
2934 | struct pci_dev *pci, | 2980 | struct pci_dev *pci, |
2935 | unsigned long device_type, | 2981 | unsigned long device_type, |
@@ -2997,9 +3043,7 @@ static int __devinit snd_intel8x0_create(struct snd_card *card, | |||
2997 | if (xbox) | 3043 | if (xbox) |
2998 | chip->xbox = 1; | 3044 | chip->xbox = 1; |
2999 | 3045 | ||
3000 | chip->inside_vm = inside_vm; | 3046 | chip->inside_vm = snd_intel8x0_inside_vm(pci); |
3001 | if (inside_vm) | ||
3002 | printk(KERN_INFO "intel8x0: enable KVM optimization\n"); | ||
3003 | 3047 | ||
3004 | if (pci->vendor == PCI_VENDOR_ID_INTEL && | 3048 | if (pci->vendor == PCI_VENDOR_ID_INTEL && |
3005 | pci->device == PCI_DEVICE_ID_INTEL_440MX) | 3049 | pci->device == PCI_DEVICE_ID_INTEL_440MX) |
@@ -3243,14 +3287,6 @@ static int __devinit snd_intel8x0_probe(struct pci_dev *pci, | |||
3243 | buggy_irq = 0; | 3287 | buggy_irq = 0; |
3244 | } | 3288 | } |
3245 | 3289 | ||
3246 | if (inside_vm < 0) { | ||
3247 | /* detect KVM and Parallels virtual environments */ | ||
3248 | inside_vm = kvm_para_available(); | ||
3249 | #if defined(__i386__) || defined(__x86_64__) | ||
3250 | inside_vm = inside_vm || boot_cpu_has(X86_FEATURE_HYPERVISOR); | ||
3251 | #endif | ||
3252 | } | ||
3253 | |||
3254 | if ((err = snd_intel8x0_create(card, pci, pci_id->driver_data, | 3290 | if ((err = snd_intel8x0_create(card, pci, pci_id->driver_data, |
3255 | &chip)) < 0) { | 3291 | &chip)) < 0) { |
3256 | snd_card_free(card); | 3292 | snd_card_free(card); |