mirror of https://gitee.com/openkylin/linux.git
Merge branch 'topic/hda-fix' into for-next
This commit is contained in:
commit
4032da5ffe
|
@ -295,6 +295,8 @@ struct hda_codec {
|
|||
|
||||
#define list_for_each_codec(c, bus) \
|
||||
list_for_each_entry(c, &(bus)->core.codec_list, core.list)
|
||||
#define list_for_each_codec_safe(c, n, bus) \
|
||||
list_for_each_entry_safe(c, n, &(bus)->core.codec_list, core.list)
|
||||
|
||||
/* snd_hda_codec_read/write optional flags */
|
||||
#define HDA_RW_NO_RESPONSE_FALLBACK (1 << 0)
|
||||
|
|
|
@ -1337,10 +1337,17 @@ EXPORT_SYMBOL_GPL(azx_probe_codecs);
|
|||
/* configure each codec instance */
|
||||
int azx_codec_configure(struct azx *chip)
|
||||
{
|
||||
struct hda_codec *codec;
|
||||
list_for_each_codec(codec, &chip->bus) {
|
||||
struct hda_codec *codec, *next;
|
||||
|
||||
/* use _safe version here since snd_hda_codec_configure() deregisters
|
||||
* the device upon error and deletes itself from the bus list.
|
||||
*/
|
||||
list_for_each_codec_safe(codec, next, &chip->bus) {
|
||||
snd_hda_codec_configure(codec);
|
||||
}
|
||||
|
||||
if (!azx_bus(chip)->num_codecs)
|
||||
return -ENODEV;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(azx_codec_configure);
|
||||
|
|
|
@ -3216,6 +3216,7 @@ static int check_dyn_adc_switch(struct hda_codec *codec)
|
|||
spec->input_paths[i][nums]);
|
||||
spec->input_paths[i][nums] =
|
||||
spec->input_paths[i][n];
|
||||
spec->input_paths[i][n] = 0;
|
||||
}
|
||||
}
|
||||
nums++;
|
||||
|
|
|
@ -1379,8 +1379,10 @@ static int azx_free(struct azx *chip)
|
|||
if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
|
||||
if (hda->need_i915_power)
|
||||
snd_hdac_display_power(bus, false);
|
||||
snd_hdac_i915_exit(bus);
|
||||
}
|
||||
if (chip->driver_type == AZX_DRIVER_PCH ||
|
||||
(chip->driver_caps & AZX_DCAPS_I915_POWERWELL))
|
||||
snd_hdac_i915_exit(bus);
|
||||
kfree(hda);
|
||||
|
||||
return 0;
|
||||
|
@ -2196,16 +2198,9 @@ static int azx_probe_continue(struct azx *chip)
|
|||
|
||||
hda->probe_continued = 1;
|
||||
|
||||
/* Request display power well for the HDA controller or codec. For
|
||||
* Haswell/Broadwell, both the display HDA controller and codec need
|
||||
* this power. For other platforms, like Baytrail/Braswell, only the
|
||||
* display codec needs the power and it can be released after probe.
|
||||
*/
|
||||
if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
|
||||
/* HSW/BDW controllers need this power */
|
||||
if (CONTROLLER_IN_GPU(pci))
|
||||
hda->need_i915_power = 1;
|
||||
|
||||
/* bind with i915 if needed */
|
||||
if (chip->driver_type == AZX_DRIVER_PCH ||
|
||||
(chip->driver_caps & AZX_DCAPS_I915_POWERWELL)) {
|
||||
err = snd_hdac_i915_init(bus);
|
||||
if (err < 0) {
|
||||
/* if the controller is bound only with HDMI/DP
|
||||
|
@ -2217,9 +2212,22 @@ static int azx_probe_continue(struct azx *chip)
|
|||
dev_err(chip->card->dev,
|
||||
"HSW/BDW HD-audio HDMI/DP requires binding with gfx driver\n");
|
||||
goto out_free;
|
||||
} else
|
||||
goto skip_i915;
|
||||
} else {
|
||||
/* don't bother any longer */
|
||||
chip->driver_caps &= ~AZX_DCAPS_I915_POWERWELL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Request display power well for the HDA controller or codec. For
|
||||
* Haswell/Broadwell, both the display HDA controller and codec need
|
||||
* this power. For other platforms, like Baytrail/Braswell, only the
|
||||
* display codec needs the power and it can be released after probe.
|
||||
*/
|
||||
if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
|
||||
/* HSW/BDW controllers need this power */
|
||||
if (CONTROLLER_IN_GPU(pci))
|
||||
hda->need_i915_power = 1;
|
||||
|
||||
err = snd_hdac_display_power(bus, true);
|
||||
if (err < 0) {
|
||||
|
@ -2229,7 +2237,6 @@ static int azx_probe_continue(struct azx *chip)
|
|||
}
|
||||
}
|
||||
|
||||
skip_i915:
|
||||
err = azx_first_init(chip);
|
||||
if (err < 0)
|
||||
goto out_free;
|
||||
|
|
|
@ -174,7 +174,6 @@ struct hdmi_spec {
|
|||
/* i915/powerwell (Haswell+/Valleyview+) specific */
|
||||
bool use_acomp_notifier; /* use i915 eld_notify callback for hotplug */
|
||||
struct i915_audio_component_audio_ops i915_audio_ops;
|
||||
bool i915_bound; /* was i915 bound in this driver? */
|
||||
|
||||
struct hdac_chmap chmap;
|
||||
hda_nid_t vendor_nid;
|
||||
|
@ -2234,8 +2233,6 @@ static void generic_spec_free(struct hda_codec *codec)
|
|||
struct hdmi_spec *spec = codec->spec;
|
||||
|
||||
if (spec) {
|
||||
if (spec->i915_bound)
|
||||
snd_hdac_i915_exit(&codec->bus->core);
|
||||
hdmi_array_free(spec);
|
||||
kfree(spec);
|
||||
codec->spec = NULL;
|
||||
|
@ -2506,19 +2503,41 @@ static void i915_pin_cvt_fixup(struct hda_codec *codec,
|
|||
}
|
||||
}
|
||||
|
||||
/* precondition and allocation for Intel codecs */
|
||||
static int alloc_intel_hdmi(struct hda_codec *codec)
|
||||
{
|
||||
/* requires i915 binding */
|
||||
if (!codec->bus->core.audio_component) {
|
||||
codec_info(codec, "No i915 binding for Intel HDMI/DP codec\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return alloc_generic_hdmi(codec);
|
||||
}
|
||||
|
||||
/* parse and post-process for Intel codecs */
|
||||
static int parse_intel_hdmi(struct hda_codec *codec)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = hdmi_parse_codec(codec);
|
||||
if (err < 0) {
|
||||
generic_spec_free(codec);
|
||||
return err;
|
||||
}
|
||||
|
||||
generic_hdmi_init_per_pins(codec);
|
||||
register_i915_notifier(codec);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Intel Haswell and onwards; audio component with eld notifier */
|
||||
static int intel_hsw_common_init(struct hda_codec *codec, hda_nid_t vendor_nid)
|
||||
{
|
||||
struct hdmi_spec *spec;
|
||||
int err;
|
||||
|
||||
/* HSW+ requires i915 binding */
|
||||
if (!codec->bus->core.audio_component) {
|
||||
codec_info(codec, "No i915 binding for Intel HDMI/DP codec\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
err = alloc_generic_hdmi(codec);
|
||||
err = alloc_intel_hdmi(codec);
|
||||
if (err < 0)
|
||||
return err;
|
||||
spec = codec->spec;
|
||||
|
@ -2542,15 +2561,7 @@ static int intel_hsw_common_init(struct hda_codec *codec, hda_nid_t vendor_nid)
|
|||
spec->ops.setup_stream = i915_hsw_setup_stream;
|
||||
spec->ops.pin_cvt_fixup = i915_pin_cvt_fixup;
|
||||
|
||||
err = hdmi_parse_codec(codec);
|
||||
if (err < 0) {
|
||||
generic_spec_free(codec);
|
||||
return err;
|
||||
}
|
||||
|
||||
generic_hdmi_init_per_pins(codec);
|
||||
register_i915_notifier(codec);
|
||||
return 0;
|
||||
return parse_intel_hdmi(codec);
|
||||
}
|
||||
|
||||
static int patch_i915_hsw_hdmi(struct hda_codec *codec)
|
||||
|
@ -2569,13 +2580,7 @@ static int patch_i915_byt_hdmi(struct hda_codec *codec)
|
|||
struct hdmi_spec *spec;
|
||||
int err;
|
||||
|
||||
/* requires i915 binding */
|
||||
if (!codec->bus->core.audio_component) {
|
||||
codec_info(codec, "No i915 binding for Intel HDMI/DP codec\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
err = alloc_generic_hdmi(codec);
|
||||
err = alloc_intel_hdmi(codec);
|
||||
if (err < 0)
|
||||
return err;
|
||||
spec = codec->spec;
|
||||
|
@ -2590,49 +2595,18 @@ static int patch_i915_byt_hdmi(struct hda_codec *codec)
|
|||
|
||||
spec->ops.pin_cvt_fixup = i915_pin_cvt_fixup;
|
||||
|
||||
err = hdmi_parse_codec(codec);
|
||||
if (err < 0) {
|
||||
generic_spec_free(codec);
|
||||
return err;
|
||||
}
|
||||
|
||||
generic_hdmi_init_per_pins(codec);
|
||||
register_i915_notifier(codec);
|
||||
return 0;
|
||||
return parse_intel_hdmi(codec);
|
||||
}
|
||||
|
||||
/* Intel IronLake, SandyBridge and IvyBridge; with eld notifier */
|
||||
static int patch_i915_cpt_hdmi(struct hda_codec *codec)
|
||||
{
|
||||
struct hdmi_spec *spec;
|
||||
int err;
|
||||
|
||||
/* no i915 component should have been bound before this */
|
||||
if (WARN_ON(codec->bus->core.audio_component))
|
||||
return -EBUSY;
|
||||
|
||||
err = alloc_generic_hdmi(codec);
|
||||
err = alloc_intel_hdmi(codec);
|
||||
if (err < 0)
|
||||
return err;
|
||||
spec = codec->spec;
|
||||
|
||||
/* Try to bind with i915 now */
|
||||
err = snd_hdac_i915_init(&codec->bus->core);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
spec->i915_bound = true;
|
||||
|
||||
err = hdmi_parse_codec(codec);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
|
||||
generic_hdmi_init_per_pins(codec);
|
||||
register_i915_notifier(codec);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
generic_spec_free(codec);
|
||||
return err;
|
||||
return parse_intel_hdmi(codec);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue