@@ -9,6 +9,7 @@
/* virtual idx for controller */
#define HDA_CODEC_IDX_CONTROLLER HDA_MAX_CODECS
+#define HDA_CODEC_RT (HDA_CODEC_IDX_CONTROLLER + 1)
#ifdef CONFIG_SND_HDA_COMPONENT
int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable);
@@ -1383,11 +1383,43 @@ static void hdac_hdmi_skl_enable_dp12(struct hdac_device *hdev)
}
+static int hdac_hdmi_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
+ struct snd_soc_dai *dai)
+{
+ struct hdac_hdmi_priv *hdmi = snd_soc_dai_get_drvdata(dai);
+ struct hdac_device *hdev = hdmi->hdev;
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ /*
+ * Maybe there is a better way to avoid using
+ * 'hdev->addr + HDA_CODEC_RT' bitmask?
+ */
+ snd_hdac_display_power(hdev->bus, hdev->addr + HDA_CODEC_RT,
+ true);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ snd_hdac_display_power(hdev->bus, hdev->addr + HDA_CODEC_RT,
+ false);
+ break;
+ default:
+ /* Nothing to do */
+ break;
+ }
+
+ return 0;
+}
+
static const struct snd_soc_dai_ops hdmi_dai_ops = {
.startup = hdac_hdmi_pcm_open,
.shutdown = hdac_hdmi_pcm_close,
.hw_params = hdac_hdmi_set_hw_params,
.set_tdm_slot = hdac_hdmi_set_tdm_slot,
+ .trigger = hdac_hdmi_pcm_trigger,
};
/*
@@ -1895,6 +1927,11 @@ static int hdmi_codec_prepare(struct device *dev)
{
struct hdac_device *hdev = dev_to_hdac_dev(dev);
+ /*
+ * FIXME: maybe using suspend/resume instead of
+ * using prepare/complete can make things simpler
+ * and no need to use 'hdev->addr + HDA_CODEC_RT'?
+ */
snd_hdac_display_power(hdev->bus, hdev->addr, true);
/*