diff options
-rw-r--r-- | sound/pci/hda/hda_i915.c | 21 | ||||
-rw-r--r-- | sound/pci/hda/hda_intel.c | 20 | ||||
-rw-r--r-- | sound/pci/hda/hda_intel.h | 5 |
3 files changed, 43 insertions, 3 deletions
diff --git a/sound/pci/hda/hda_i915.c b/sound/pci/hda/hda_i915.c index d9d079330e55..852170258266 100644 --- a/sound/pci/hda/hda_i915.c +++ b/sound/pci/hda/hda_i915.c @@ -33,6 +33,27 @@ #define AZX_REG_EM4 0x100c #define AZX_REG_EM5 0x1010 +int hda_set_codec_wakeup(struct hda_intel *hda, bool enable) +{ + struct i915_audio_component *acomp = &hda->audio_component; + + if (!acomp->ops) + return -ENODEV; + + if (!acomp->ops->codec_wake_override) { + dev_warn(&hda->chip.pci->dev, + "Invalid codec wake callback\n"); + return 0; + } + + dev_dbg(&hda->chip.pci->dev, "%s codec wakeup\n", + enable ? "enable" : "disable"); + + acomp->ops->codec_wake_override(acomp->dev, enable); + + return 0; +} + int hda_display_power(struct hda_intel *hda, bool enable) { struct i915_audio_component *acomp = &hda->audio_component; diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 87df90d245bc..706879a97608 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -491,6 +491,17 @@ static void azx_init_pci(struct azx *chip) } } +static void hda_intel_init_chip(struct azx *chip, bool full_reset) +{ + struct hda_intel *hda = container_of(chip, struct hda_intel, chip); + + if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) + hda_set_codec_wakeup(hda, true); + azx_init_chip(chip, full_reset); + if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) + hda_set_codec_wakeup(hda, false); +} + /* calculate runtime delay from LPIB */ static int azx_get_delay_from_lpib(struct azx *chip, struct azx_dev *azx_dev, unsigned int pos) @@ -850,7 +861,7 @@ static int azx_resume(struct device *dev) return -EIO; azx_init_pci(chip); - azx_init_chip(chip, true); + hda_intel_init_chip(chip, true); snd_power_change_state(card, SNDRV_CTL_POWER_D0); return 0; @@ -912,13 +923,16 @@ static int azx_runtime_resume(struct device *dev) && hda->need_i915_power) { hda_display_power(hda, true); haswell_set_bclk(hda); + /* toggle codec wakeup bit for STATESTS read */ + hda_set_codec_wakeup(hda, true); + hda_set_codec_wakeup(hda, false); } /* Read STATESTS before controller reset */ status = azx_readw(chip, STATESTS); azx_init_pci(chip); - azx_init_chip(chip, true); + hda_intel_init_chip(chip, true); if (status) { list_for_each_codec(codec, &chip->bus) @@ -1629,7 +1643,7 @@ static int azx_first_init(struct azx *chip) haswell_set_bclk(hda); } - azx_init_chip(chip, (probe_only[dev] & 2) == 0); + hda_intel_init_chip(chip, (probe_only[dev] & 2) == 0); /* codec detection */ if (!azx_bus(chip)->codec_mask) { diff --git a/sound/pci/hda/hda_intel.h b/sound/pci/hda/hda_intel.h index ff41fc30091d..7fd3254a2f3f 100644 --- a/sound/pci/hda/hda_intel.h +++ b/sound/pci/hda/hda_intel.h @@ -51,11 +51,16 @@ struct hda_intel { }; #ifdef CONFIG_SND_HDA_I915 +int hda_set_codec_wakeup(struct hda_intel *hda, bool enable); int hda_display_power(struct hda_intel *hda, bool enable); void haswell_set_bclk(struct hda_intel *hda); int hda_i915_init(struct hda_intel *hda); int hda_i915_exit(struct hda_intel *hda); #else +static inline int hda_set_codec_wakeup(struct hda_intel *hda, bool enable) +{ + return 0; +} static inline int hda_display_power(struct hda_intel *hda, bool enable) { return 0; |