diff options
Diffstat (limited to 'sound/pci/hda/patch_hdmi.c')
-rw-r--r-- | sound/pci/hda/patch_hdmi.c | 104 |
1 files changed, 39 insertions, 65 deletions
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 90e4ff87445e..76c85f08bea6 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c | |||
@@ -174,7 +174,6 @@ struct hdmi_spec { | |||
174 | /* i915/powerwell (Haswell+/Valleyview+) specific */ | 174 | /* i915/powerwell (Haswell+/Valleyview+) specific */ |
175 | bool use_acomp_notifier; /* use i915 eld_notify callback for hotplug */ | 175 | bool use_acomp_notifier; /* use i915 eld_notify callback for hotplug */ |
176 | struct i915_audio_component_audio_ops i915_audio_ops; | 176 | struct i915_audio_component_audio_ops i915_audio_ops; |
177 | bool i915_bound; /* was i915 bound in this driver? */ | ||
178 | 177 | ||
179 | struct hdac_chmap chmap; | 178 | struct hdac_chmap chmap; |
180 | hda_nid_t vendor_nid; | 179 | hda_nid_t vendor_nid; |
@@ -2234,8 +2233,6 @@ static void generic_spec_free(struct hda_codec *codec) | |||
2234 | struct hdmi_spec *spec = codec->spec; | 2233 | struct hdmi_spec *spec = codec->spec; |
2235 | 2234 | ||
2236 | if (spec) { | 2235 | if (spec) { |
2237 | if (spec->i915_bound) | ||
2238 | snd_hdac_i915_exit(&codec->bus->core); | ||
2239 | hdmi_array_free(spec); | 2236 | hdmi_array_free(spec); |
2240 | kfree(spec); | 2237 | kfree(spec); |
2241 | codec->spec = NULL; | 2238 | codec->spec = NULL; |
@@ -2506,19 +2503,41 @@ static void i915_pin_cvt_fixup(struct hda_codec *codec, | |||
2506 | } | 2503 | } |
2507 | } | 2504 | } |
2508 | 2505 | ||
2509 | /* Intel Haswell and onwards; audio component with eld notifier */ | 2506 | /* precondition and allocation for Intel codecs */ |
2510 | static int intel_hsw_common_init(struct hda_codec *codec, hda_nid_t vendor_nid) | 2507 | static int alloc_intel_hdmi(struct hda_codec *codec) |
2511 | { | 2508 | { |
2512 | struct hdmi_spec *spec; | 2509 | /* requires i915 binding */ |
2513 | int err; | ||
2514 | |||
2515 | /* HSW+ requires i915 binding */ | ||
2516 | if (!codec->bus->core.audio_component) { | 2510 | if (!codec->bus->core.audio_component) { |
2517 | codec_info(codec, "No i915 binding for Intel HDMI/DP codec\n"); | 2511 | codec_info(codec, "No i915 binding for Intel HDMI/DP codec\n"); |
2518 | return -ENODEV; | 2512 | return -ENODEV; |
2519 | } | 2513 | } |
2520 | 2514 | ||
2521 | err = alloc_generic_hdmi(codec); | 2515 | return alloc_generic_hdmi(codec); |
2516 | } | ||
2517 | |||
2518 | /* parse and post-process for Intel codecs */ | ||
2519 | static int parse_intel_hdmi(struct hda_codec *codec) | ||
2520 | { | ||
2521 | int err; | ||
2522 | |||
2523 | err = hdmi_parse_codec(codec); | ||
2524 | if (err < 0) { | ||
2525 | generic_spec_free(codec); | ||
2526 | return err; | ||
2527 | } | ||
2528 | |||
2529 | generic_hdmi_init_per_pins(codec); | ||
2530 | register_i915_notifier(codec); | ||
2531 | return 0; | ||
2532 | } | ||
2533 | |||
2534 | /* Intel Haswell and onwards; audio component with eld notifier */ | ||
2535 | static int intel_hsw_common_init(struct hda_codec *codec, hda_nid_t vendor_nid) | ||
2536 | { | ||
2537 | struct hdmi_spec *spec; | ||
2538 | int err; | ||
2539 | |||
2540 | err = alloc_intel_hdmi(codec); | ||
2522 | if (err < 0) | 2541 | if (err < 0) |
2523 | return err; | 2542 | return err; |
2524 | spec = codec->spec; | 2543 | spec = codec->spec; |
@@ -2542,15 +2561,7 @@ static int intel_hsw_common_init(struct hda_codec *codec, hda_nid_t vendor_nid) | |||
2542 | spec->ops.setup_stream = i915_hsw_setup_stream; | 2561 | spec->ops.setup_stream = i915_hsw_setup_stream; |
2543 | spec->ops.pin_cvt_fixup = i915_pin_cvt_fixup; | 2562 | spec->ops.pin_cvt_fixup = i915_pin_cvt_fixup; |
2544 | 2563 | ||
2545 | err = hdmi_parse_codec(codec); | 2564 | return parse_intel_hdmi(codec); |
2546 | if (err < 0) { | ||
2547 | generic_spec_free(codec); | ||
2548 | return err; | ||
2549 | } | ||
2550 | |||
2551 | generic_hdmi_init_per_pins(codec); | ||
2552 | register_i915_notifier(codec); | ||
2553 | return 0; | ||
2554 | } | 2565 | } |
2555 | 2566 | ||
2556 | static int patch_i915_hsw_hdmi(struct hda_codec *codec) | 2567 | static int patch_i915_hsw_hdmi(struct hda_codec *codec) |
@@ -2569,13 +2580,7 @@ static int patch_i915_byt_hdmi(struct hda_codec *codec) | |||
2569 | struct hdmi_spec *spec; | 2580 | struct hdmi_spec *spec; |
2570 | int err; | 2581 | int err; |
2571 | 2582 | ||
2572 | /* requires i915 binding */ | 2583 | err = alloc_intel_hdmi(codec); |
2573 | if (!codec->bus->core.audio_component) { | ||
2574 | codec_info(codec, "No i915 binding for Intel HDMI/DP codec\n"); | ||
2575 | return -ENODEV; | ||
2576 | } | ||
2577 | |||
2578 | err = alloc_generic_hdmi(codec); | ||
2579 | if (err < 0) | 2584 | if (err < 0) |
2580 | return err; | 2585 | return err; |
2581 | spec = codec->spec; | 2586 | spec = codec->spec; |
@@ -2590,49 +2595,18 @@ static int patch_i915_byt_hdmi(struct hda_codec *codec) | |||
2590 | 2595 | ||
2591 | spec->ops.pin_cvt_fixup = i915_pin_cvt_fixup; | 2596 | spec->ops.pin_cvt_fixup = i915_pin_cvt_fixup; |
2592 | 2597 | ||
2593 | err = hdmi_parse_codec(codec); | 2598 | return parse_intel_hdmi(codec); |
2594 | if (err < 0) { | ||
2595 | generic_spec_free(codec); | ||
2596 | return err; | ||
2597 | } | ||
2598 | |||
2599 | generic_hdmi_init_per_pins(codec); | ||
2600 | register_i915_notifier(codec); | ||
2601 | return 0; | ||
2602 | } | 2599 | } |
2603 | 2600 | ||
2604 | /* Intel IronLake, SandyBridge and IvyBridge; with eld notifier */ | 2601 | /* Intel IronLake, SandyBridge and IvyBridge; with eld notifier */ |
2605 | static int patch_i915_cpt_hdmi(struct hda_codec *codec) | 2602 | static int patch_i915_cpt_hdmi(struct hda_codec *codec) |
2606 | { | 2603 | { |
2607 | struct hdmi_spec *spec; | ||
2608 | int err; | 2604 | int err; |
2609 | 2605 | ||
2610 | /* no i915 component should have been bound before this */ | 2606 | err = alloc_intel_hdmi(codec); |
2611 | if (WARN_ON(codec->bus->core.audio_component)) | ||
2612 | return -EBUSY; | ||
2613 | |||
2614 | err = alloc_generic_hdmi(codec); | ||
2615 | if (err < 0) | 2607 | if (err < 0) |
2616 | return err; | 2608 | return err; |
2617 | spec = codec->spec; | 2609 | return parse_intel_hdmi(codec); |
2618 | |||
2619 | /* Try to bind with i915 now */ | ||
2620 | err = snd_hdac_i915_init(&codec->bus->core); | ||
2621 | if (err < 0) | ||
2622 | goto error; | ||
2623 | spec->i915_bound = true; | ||
2624 | |||
2625 | err = hdmi_parse_codec(codec); | ||
2626 | if (err < 0) | ||
2627 | goto error; | ||
2628 | |||
2629 | generic_hdmi_init_per_pins(codec); | ||
2630 | register_i915_notifier(codec); | ||
2631 | return 0; | ||
2632 | |||
2633 | error: | ||
2634 | generic_spec_free(codec); | ||
2635 | return err; | ||
2636 | } | 2610 | } |
2637 | 2611 | ||
2638 | /* | 2612 | /* |
@@ -2782,21 +2756,21 @@ static int nvhdmi_7x_init_8ch(struct hda_codec *codec) | |||
2782 | return 0; | 2756 | return 0; |
2783 | } | 2757 | } |
2784 | 2758 | ||
2785 | static unsigned int channels_2_6_8[] = { | 2759 | static const unsigned int channels_2_6_8[] = { |
2786 | 2, 6, 8 | 2760 | 2, 6, 8 |
2787 | }; | 2761 | }; |
2788 | 2762 | ||
2789 | static unsigned int channels_2_8[] = { | 2763 | static const unsigned int channels_2_8[] = { |
2790 | 2, 8 | 2764 | 2, 8 |
2791 | }; | 2765 | }; |
2792 | 2766 | ||
2793 | static struct snd_pcm_hw_constraint_list hw_constraints_2_6_8_channels = { | 2767 | static const struct snd_pcm_hw_constraint_list hw_constraints_2_6_8_channels = { |
2794 | .count = ARRAY_SIZE(channels_2_6_8), | 2768 | .count = ARRAY_SIZE(channels_2_6_8), |
2795 | .list = channels_2_6_8, | 2769 | .list = channels_2_6_8, |
2796 | .mask = 0, | 2770 | .mask = 0, |
2797 | }; | 2771 | }; |
2798 | 2772 | ||
2799 | static struct snd_pcm_hw_constraint_list hw_constraints_2_8_channels = { | 2773 | static const struct snd_pcm_hw_constraint_list hw_constraints_2_8_channels = { |
2800 | .count = ARRAY_SIZE(channels_2_8), | 2774 | .count = ARRAY_SIZE(channels_2_8), |
2801 | .list = channels_2_8, | 2775 | .list = channels_2_8, |
2802 | .mask = 0, | 2776 | .mask = 0, |
@@ -2807,7 +2781,7 @@ static int simple_playback_pcm_open(struct hda_pcm_stream *hinfo, | |||
2807 | struct snd_pcm_substream *substream) | 2781 | struct snd_pcm_substream *substream) |
2808 | { | 2782 | { |
2809 | struct hdmi_spec *spec = codec->spec; | 2783 | struct hdmi_spec *spec = codec->spec; |
2810 | struct snd_pcm_hw_constraint_list *hw_constraints_channels = NULL; | 2784 | const struct snd_pcm_hw_constraint_list *hw_constraints_channels = NULL; |
2811 | 2785 | ||
2812 | switch (codec->preset->vendor_id) { | 2786 | switch (codec->preset->vendor_id) { |
2813 | case 0x10de0002: | 2787 | case 0x10de0002: |