diff options
| -rw-r--r-- | sound/pci/hda/hda_codec.c | 10 | ||||
| -rw-r--r-- | sound/pci/hda/hda_hwdep.c | 2 | ||||
| -rw-r--r-- | sound/pci/hda/hda_local.h | 2 | ||||
| -rw-r--r-- | sound/pci/hda/patch_analog.c | 15 | ||||
| -rw-r--r-- | sound/pci/hda/patch_intelhdmi.c | 61 | ||||
| -rw-r--r-- | sound/pci/hda/patch_realtek.c | 1 | ||||
| -rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 13 |
7 files changed, 71 insertions, 33 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 0b708134d12f..d03f99298be9 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
| @@ -3088,6 +3088,16 @@ int snd_hda_multi_out_dig_prepare(struct hda_codec *codec, | |||
| 3088 | } | 3088 | } |
| 3089 | EXPORT_SYMBOL_HDA(snd_hda_multi_out_dig_prepare); | 3089 | EXPORT_SYMBOL_HDA(snd_hda_multi_out_dig_prepare); |
| 3090 | 3090 | ||
| 3091 | int snd_hda_multi_out_dig_cleanup(struct hda_codec *codec, | ||
| 3092 | struct hda_multi_out *mout) | ||
| 3093 | { | ||
| 3094 | mutex_lock(&codec->spdif_mutex); | ||
| 3095 | cleanup_dig_out_stream(codec, mout->dig_out_nid); | ||
| 3096 | mutex_unlock(&codec->spdif_mutex); | ||
| 3097 | return 0; | ||
| 3098 | } | ||
| 3099 | EXPORT_SYMBOL_HDA(snd_hda_multi_out_dig_cleanup); | ||
| 3100 | |||
| 3091 | /* | 3101 | /* |
| 3092 | * release the digital out | 3102 | * release the digital out |
| 3093 | */ | 3103 | */ |
diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c index 300ab407cf42..482fb0304ca9 100644 --- a/sound/pci/hda/hda_hwdep.c +++ b/sound/pci/hda/hda_hwdep.c | |||
| @@ -175,7 +175,7 @@ static int reconfig_codec(struct hda_codec *codec) | |||
| 175 | err = snd_hda_codec_build_controls(codec); | 175 | err = snd_hda_codec_build_controls(codec); |
| 176 | if (err < 0) | 176 | if (err < 0) |
| 177 | return err; | 177 | return err; |
| 178 | return 0; | 178 | return snd_card_register(codec->bus->card); |
| 179 | } | 179 | } |
| 180 | 180 | ||
| 181 | /* | 181 | /* |
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 1dd8716c387f..44f189cb97ae 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h | |||
| @@ -251,6 +251,8 @@ int snd_hda_multi_out_dig_prepare(struct hda_codec *codec, | |||
| 251 | unsigned int stream_tag, | 251 | unsigned int stream_tag, |
| 252 | unsigned int format, | 252 | unsigned int format, |
| 253 | struct snd_pcm_substream *substream); | 253 | struct snd_pcm_substream *substream); |
| 254 | int snd_hda_multi_out_dig_cleanup(struct hda_codec *codec, | ||
| 255 | struct hda_multi_out *mout); | ||
| 254 | int snd_hda_multi_out_analog_open(struct hda_codec *codec, | 256 | int snd_hda_multi_out_analog_open(struct hda_codec *codec, |
| 255 | struct hda_multi_out *mout, | 257 | struct hda_multi_out *mout, |
| 256 | struct snd_pcm_substream *substream, | 258 | struct snd_pcm_substream *substream, |
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 2e7371ec2e23..e48612323aa0 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
| @@ -275,6 +275,14 @@ static int ad198x_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
| 275 | format, substream); | 275 | format, substream); |
| 276 | } | 276 | } |
| 277 | 277 | ||
| 278 | static int ad198x_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
| 279 | struct hda_codec *codec, | ||
| 280 | struct snd_pcm_substream *substream) | ||
| 281 | { | ||
| 282 | struct ad198x_spec *spec = codec->spec; | ||
| 283 | return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout); | ||
| 284 | } | ||
| 285 | |||
| 278 | /* | 286 | /* |
| 279 | * Analog capture | 287 | * Analog capture |
| 280 | */ | 288 | */ |
| @@ -333,7 +341,8 @@ static struct hda_pcm_stream ad198x_pcm_digital_playback = { | |||
| 333 | .ops = { | 341 | .ops = { |
| 334 | .open = ad198x_dig_playback_pcm_open, | 342 | .open = ad198x_dig_playback_pcm_open, |
| 335 | .close = ad198x_dig_playback_pcm_close, | 343 | .close = ad198x_dig_playback_pcm_close, |
| 336 | .prepare = ad198x_dig_playback_pcm_prepare | 344 | .prepare = ad198x_dig_playback_pcm_prepare, |
| 345 | .cleanup = ad198x_dig_playback_pcm_cleanup | ||
| 337 | }, | 346 | }, |
| 338 | }; | 347 | }; |
| 339 | 348 | ||
| @@ -1885,8 +1894,8 @@ static hda_nid_t ad1988_capsrc_nids[3] = { | |||
| 1885 | #define AD1988_SPDIF_OUT_HDMI 0x0b | 1894 | #define AD1988_SPDIF_OUT_HDMI 0x0b |
| 1886 | #define AD1988_SPDIF_IN 0x07 | 1895 | #define AD1988_SPDIF_IN 0x07 |
| 1887 | 1896 | ||
| 1888 | static hda_nid_t ad1989b_slave_dig_outs[2] = { | 1897 | static hda_nid_t ad1989b_slave_dig_outs[] = { |
| 1889 | AD1988_SPDIF_OUT, AD1988_SPDIF_OUT_HDMI | 1898 | AD1988_SPDIF_OUT, AD1988_SPDIF_OUT_HDMI, 0 |
| 1890 | }; | 1899 | }; |
| 1891 | 1900 | ||
| 1892 | static struct hda_input_mux ad1988_6stack_capture_source = { | 1901 | static struct hda_input_mux ad1988_6stack_capture_source = { |
diff --git a/sound/pci/hda/patch_intelhdmi.c b/sound/pci/hda/patch_intelhdmi.c index 3564f4e4b74c..fcc77fec4487 100644 --- a/sound/pci/hda/patch_intelhdmi.c +++ b/sound/pci/hda/patch_intelhdmi.c | |||
| @@ -49,11 +49,6 @@ static struct hda_verb pinout_enable_verb[] = { | |||
| 49 | {} /* terminator */ | 49 | {} /* terminator */ |
| 50 | }; | 50 | }; |
| 51 | 51 | ||
| 52 | static struct hda_verb pinout_disable_verb[] = { | ||
| 53 | {PIN_NID, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00}, | ||
| 54 | {} | ||
| 55 | }; | ||
| 56 | |||
| 57 | static struct hda_verb unsolicited_response_verb[] = { | 52 | static struct hda_verb unsolicited_response_verb[] = { |
| 58 | {PIN_NID, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | | 53 | {PIN_NID, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | |
| 59 | INTEL_HDMI_EVENT_TAG}, | 54 | INTEL_HDMI_EVENT_TAG}, |
| @@ -248,10 +243,6 @@ static void hdmi_write_dip_byte(struct hda_codec *codec, hda_nid_t nid, | |||
| 248 | 243 | ||
| 249 | static void hdmi_enable_output(struct hda_codec *codec) | 244 | static void hdmi_enable_output(struct hda_codec *codec) |
| 250 | { | 245 | { |
| 251 | /* Enable Audio InfoFrame Transmission */ | ||
| 252 | hdmi_set_dip_index(codec, PIN_NID, 0x0, 0x0); | ||
| 253 | snd_hda_codec_write(codec, PIN_NID, 0, AC_VERB_SET_HDMI_DIP_XMIT, | ||
| 254 | AC_DIPXMIT_BEST); | ||
| 255 | /* Unmute */ | 246 | /* Unmute */ |
| 256 | if (get_wcaps(codec, PIN_NID) & AC_WCAP_OUT_AMP) | 247 | if (get_wcaps(codec, PIN_NID) & AC_WCAP_OUT_AMP) |
| 257 | snd_hda_codec_write(codec, PIN_NID, 0, | 248 | snd_hda_codec_write(codec, PIN_NID, 0, |
| @@ -260,17 +251,24 @@ static void hdmi_enable_output(struct hda_codec *codec) | |||
| 260 | snd_hda_sequence_write(codec, pinout_enable_verb); | 251 | snd_hda_sequence_write(codec, pinout_enable_verb); |
| 261 | } | 252 | } |
| 262 | 253 | ||
| 263 | static void hdmi_disable_output(struct hda_codec *codec) | 254 | /* |
| 255 | * Enable Audio InfoFrame Transmission | ||
| 256 | */ | ||
| 257 | static void hdmi_start_infoframe_trans(struct hda_codec *codec) | ||
| 264 | { | 258 | { |
| 265 | snd_hda_sequence_write(codec, pinout_disable_verb); | 259 | hdmi_set_dip_index(codec, PIN_NID, 0x0, 0x0); |
| 266 | if (get_wcaps(codec, PIN_NID) & AC_WCAP_OUT_AMP) | 260 | snd_hda_codec_write(codec, PIN_NID, 0, AC_VERB_SET_HDMI_DIP_XMIT, |
| 267 | snd_hda_codec_write(codec, PIN_NID, 0, | 261 | AC_DIPXMIT_BEST); |
| 268 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); | 262 | } |
| 269 | 263 | ||
| 270 | /* | 264 | /* |
| 271 | * FIXME: noises may arise when playing music after reloading the | 265 | * Disable Audio InfoFrame Transmission |
| 272 | * kernel module, until the next X restart or monitor repower. | 266 | */ |
| 273 | */ | 267 | static void hdmi_stop_infoframe_trans(struct hda_codec *codec) |
| 268 | { | ||
| 269 | hdmi_set_dip_index(codec, PIN_NID, 0x0, 0x0); | ||
| 270 | snd_hda_codec_write(codec, PIN_NID, 0, AC_VERB_SET_HDMI_DIP_XMIT, | ||
| 271 | AC_DIPXMIT_DISABLE); | ||
| 274 | } | 272 | } |
| 275 | 273 | ||
| 276 | static int hdmi_get_channel_count(struct hda_codec *codec) | 274 | static int hdmi_get_channel_count(struct hda_codec *codec) |
| @@ -368,11 +366,16 @@ static void hdmi_fill_audio_infoframe(struct hda_codec *codec, | |||
| 368 | struct hdmi_audio_infoframe *ai) | 366 | struct hdmi_audio_infoframe *ai) |
| 369 | { | 367 | { |
| 370 | u8 *params = (u8 *)ai; | 368 | u8 *params = (u8 *)ai; |
| 369 | u8 sum = 0; | ||
| 371 | int i; | 370 | int i; |
| 372 | 371 | ||
| 373 | hdmi_debug_dip_size(codec); | 372 | hdmi_debug_dip_size(codec); |
| 374 | hdmi_clear_dip_buffers(codec); /* be paranoid */ | 373 | hdmi_clear_dip_buffers(codec); /* be paranoid */ |
| 375 | 374 | ||
| 375 | for (i = 0; i < sizeof(ai); i++) | ||
| 376 | sum += params[i]; | ||
| 377 | ai->checksum = - sum; | ||
| 378 | |||
| 376 | hdmi_set_dip_index(codec, PIN_NID, 0x0, 0x0); | 379 | hdmi_set_dip_index(codec, PIN_NID, 0x0, 0x0); |
| 377 | for (i = 0; i < sizeof(ai); i++) | 380 | for (i = 0; i < sizeof(ai); i++) |
| 378 | hdmi_write_dip_byte(codec, PIN_NID, params[i]); | 381 | hdmi_write_dip_byte(codec, PIN_NID, params[i]); |
| @@ -419,14 +422,18 @@ static int hdmi_setup_channel_allocation(struct hda_codec *codec, | |||
| 419 | /* | 422 | /* |
| 420 | * CA defaults to 0 for basic stereo audio | 423 | * CA defaults to 0 for basic stereo audio |
| 421 | */ | 424 | */ |
| 422 | if (!eld->eld_ver) | ||
| 423 | return 0; | ||
| 424 | if (!eld->spk_alloc) | ||
| 425 | return 0; | ||
| 426 | if (channels <= 2) | 425 | if (channels <= 2) |
| 427 | return 0; | 426 | return 0; |
| 428 | 427 | ||
| 429 | /* | 428 | /* |
| 429 | * HDMI sink's ELD info cannot always be retrieved for now, e.g. | ||
| 430 | * in console or for audio devices. Assume the highest speakers | ||
| 431 | * configuration, to _not_ prohibit multi-channel audio playback. | ||
| 432 | */ | ||
| 433 | if (!eld->spk_alloc) | ||
| 434 | eld->spk_alloc = 0xffff; | ||
| 435 | |||
| 436 | /* | ||
| 430 | * expand ELD's speaker allocation mask | 437 | * expand ELD's speaker allocation mask |
| 431 | * | 438 | * |
| 432 | * ELD tells the speaker mask in a compact(paired) form, | 439 | * ELD tells the speaker mask in a compact(paired) form, |
| @@ -485,6 +492,7 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, | |||
| 485 | hdmi_setup_channel_mapping(codec, &ai); | 492 | hdmi_setup_channel_mapping(codec, &ai); |
| 486 | 493 | ||
| 487 | hdmi_fill_audio_infoframe(codec, &ai); | 494 | hdmi_fill_audio_infoframe(codec, &ai); |
| 495 | hdmi_start_infoframe_trans(codec); | ||
| 488 | } | 496 | } |
| 489 | 497 | ||
| 490 | 498 | ||
| @@ -562,7 +570,7 @@ static int intel_hdmi_playback_pcm_close(struct hda_pcm_stream *hinfo, | |||
| 562 | { | 570 | { |
| 563 | struct intel_hdmi_spec *spec = codec->spec; | 571 | struct intel_hdmi_spec *spec = codec->spec; |
| 564 | 572 | ||
| 565 | hdmi_disable_output(codec); | 573 | hdmi_stop_infoframe_trans(codec); |
| 566 | 574 | ||
| 567 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); | 575 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); |
| 568 | } | 576 | } |
| @@ -582,8 +590,6 @@ static int intel_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
| 582 | 590 | ||
| 583 | hdmi_setup_audio_infoframe(codec, substream); | 591 | hdmi_setup_audio_infoframe(codec, substream); |
| 584 | 592 | ||
| 585 | hdmi_enable_output(codec); | ||
| 586 | |||
| 587 | return 0; | 593 | return 0; |
| 588 | } | 594 | } |
| 589 | 595 | ||
| @@ -628,8 +634,7 @@ static int intel_hdmi_build_controls(struct hda_codec *codec) | |||
| 628 | 634 | ||
| 629 | static int intel_hdmi_init(struct hda_codec *codec) | 635 | static int intel_hdmi_init(struct hda_codec *codec) |
| 630 | { | 636 | { |
| 631 | /* disable audio output as early as possible */ | 637 | hdmi_enable_output(codec); |
| 632 | hdmi_disable_output(codec); | ||
| 633 | 638 | ||
| 634 | snd_hda_sequence_write(codec, unsolicited_response_verb); | 639 | snd_hda_sequence_write(codec, unsolicited_response_verb); |
| 635 | 640 | ||
| @@ -679,6 +684,7 @@ static struct hda_codec_preset snd_hda_preset_intelhdmi[] = { | |||
| 679 | { .id = 0x80862801, .name = "G45 DEVBLC", .patch = patch_intel_hdmi }, | 684 | { .id = 0x80862801, .name = "G45 DEVBLC", .patch = patch_intel_hdmi }, |
| 680 | { .id = 0x80862802, .name = "G45 DEVCTG", .patch = patch_intel_hdmi }, | 685 | { .id = 0x80862802, .name = "G45 DEVCTG", .patch = patch_intel_hdmi }, |
| 681 | { .id = 0x80862803, .name = "G45 DEVELK", .patch = patch_intel_hdmi }, | 686 | { .id = 0x80862803, .name = "G45 DEVELK", .patch = patch_intel_hdmi }, |
| 687 | { .id = 0x80862804, .name = "G45 DEVIBX", .patch = patch_intel_hdmi }, | ||
| 682 | { .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_intel_hdmi }, | 688 | { .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_intel_hdmi }, |
| 683 | {} /* terminator */ | 689 | {} /* terminator */ |
| 684 | }; | 690 | }; |
| @@ -687,6 +693,7 @@ MODULE_ALIAS("snd-hda-codec-id:808629fb"); | |||
| 687 | MODULE_ALIAS("snd-hda-codec-id:80862801"); | 693 | MODULE_ALIAS("snd-hda-codec-id:80862801"); |
| 688 | MODULE_ALIAS("snd-hda-codec-id:80862802"); | 694 | MODULE_ALIAS("snd-hda-codec-id:80862802"); |
| 689 | MODULE_ALIAS("snd-hda-codec-id:80862803"); | 695 | MODULE_ALIAS("snd-hda-codec-id:80862803"); |
| 696 | MODULE_ALIAS("snd-hda-codec-id:80862804"); | ||
| 690 | MODULE_ALIAS("snd-hda-codec-id:10951392"); | 697 | MODULE_ALIAS("snd-hda-codec-id:10951392"); |
| 691 | 698 | ||
| 692 | MODULE_LICENSE("GPL"); | 699 | MODULE_LICENSE("GPL"); |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index ae5c8a0d1479..ed8fcbd60003 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
| @@ -8478,6 +8478,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { | |||
| 8478 | SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP), | 8478 | SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP), |
| 8479 | SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V), | 8479 | SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V), |
| 8480 | SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG), | 8480 | SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG), |
| 8481 | SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG), | ||
| 8481 | SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q), | 8482 | SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q), |
| 8482 | SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601), | 8483 | SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601), |
| 8483 | SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG), | 8484 | SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG), |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 38428e22428f..8027edf3c8f2 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
| @@ -1799,7 +1799,7 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { | |||
| 1799 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f2, | 1799 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f2, |
| 1800 | "HP dv5", STAC_HP_M4), | 1800 | "HP dv5", STAC_HP_M4), |
| 1801 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f4, | 1801 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f4, |
| 1802 | "HP dv7", STAC_HP_M4), | 1802 | "HP dv7", STAC_HP_DV5), |
| 1803 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f7, | 1803 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f7, |
| 1804 | "HP dv4", STAC_HP_DV5), | 1804 | "HP dv4", STAC_HP_DV5), |
| 1805 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30fc, | 1805 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30fc, |
| @@ -2442,6 +2442,14 @@ static int stac92xx_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
| 2442 | stream_tag, format, substream); | 2442 | stream_tag, format, substream); |
| 2443 | } | 2443 | } |
| 2444 | 2444 | ||
| 2445 | static int stac92xx_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
| 2446 | struct hda_codec *codec, | ||
| 2447 | struct snd_pcm_substream *substream) | ||
| 2448 | { | ||
| 2449 | struct sigmatel_spec *spec = codec->spec; | ||
| 2450 | return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout); | ||
| 2451 | } | ||
| 2452 | |||
| 2445 | 2453 | ||
| 2446 | /* | 2454 | /* |
| 2447 | * Analog capture callbacks | 2455 | * Analog capture callbacks |
| @@ -2486,7 +2494,8 @@ static struct hda_pcm_stream stac92xx_pcm_digital_playback = { | |||
| 2486 | .ops = { | 2494 | .ops = { |
| 2487 | .open = stac92xx_dig_playback_pcm_open, | 2495 | .open = stac92xx_dig_playback_pcm_open, |
| 2488 | .close = stac92xx_dig_playback_pcm_close, | 2496 | .close = stac92xx_dig_playback_pcm_close, |
| 2489 | .prepare = stac92xx_dig_playback_pcm_prepare | 2497 | .prepare = stac92xx_dig_playback_pcm_prepare, |
| 2498 | .cleanup = stac92xx_dig_playback_pcm_cleanup | ||
| 2490 | }, | 2499 | }, |
| 2491 | }; | 2500 | }; |
| 2492 | 2501 | ||
