summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sound/pci/hda/hda_i915.c21
-rw-r--r--sound/pci/hda/hda_intel.c20
-rw-r--r--sound/pci/hda/hda_intel.h5
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;