^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) // This file is provided under a dual BSD/GPLv2 license. When using or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) // redistributing this file, you may do so under either license.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) // Copyright(c) 2018 Intel Corporation. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) // Authors: Keyon Jie <yang.jie@linux.intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <sound/hdaudio_ext.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <sound/hda_register.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <sound/hda_codec.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <sound/hda_i915.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <sound/sof.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "../ops.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "hda.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "../../codecs/hdac_hda.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #endif /* CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define IDISP_VID_INTEL 0x80860000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) /* load the legacy HDA codec driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) static int request_codec_module(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #ifdef MODULE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) char alias[MODULE_NAME_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) const char *mod = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) switch (codec->probe_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) case HDA_CODEC_ID_GENERIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #if IS_MODULE(CONFIG_SND_HDA_GENERIC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) mod = "snd-hda-codec-generic";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) snd_hdac_codec_modalias(&codec->core, alias, sizeof(alias));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) mod = alias;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) if (mod) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) dev_dbg(&codec->core.dev, "loading codec module: %s\n", mod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) request_module(mod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #endif /* MODULE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) return device_attach(hda_codec_dev(codec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) static int hda_codec_load_module(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) int ret = request_codec_module(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) if (ret <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) codec->probe_id = HDA_CODEC_ID_GENERIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) ret = request_codec_module(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /* enable controller wake up event for all codecs with jack connectors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) struct hda_bus *hbus = sof_to_hbus(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct hdac_bus *bus = sof_to_bus(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) struct hda_codec *codec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) unsigned int mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) list_for_each_codec(codec, hbus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) if (codec->jacktbl.used)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) mask |= BIT(codec->core.addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) snd_hdac_chip_updatew(bus, WAKEEN, STATESTS_INT_MASK, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) /* check jack status after resuming from suspend mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) void hda_codec_jack_check(struct snd_sof_dev *sdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct hda_bus *hbus = sof_to_hbus(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) struct hdac_bus *bus = sof_to_bus(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) struct hda_codec *codec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /* disable controller Wake Up event*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) snd_hdac_chip_updatew(bus, WAKEEN, STATESTS_INT_MASK, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) list_for_each_codec(codec, hbus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * Wake up all jack-detecting codecs regardless whether an event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * has been recorded in STATESTS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if (codec->jacktbl.used)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) pm_request_resume(&codec->core.dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) void hda_codec_jack_check(struct snd_sof_dev *sdev) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #endif /* CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) EXPORT_SYMBOL_NS(hda_codec_jack_wake_enable, SND_SOC_SOF_HDA_AUDIO_CODEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) EXPORT_SYMBOL_NS(hda_codec_jack_check, SND_SOC_SOF_HDA_AUDIO_CODEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #if IS_ENABLED(CONFIG_SND_HDA_GENERIC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define is_generic_config(bus) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) ((bus)->modelname && !strcmp((bus)->modelname, "generic"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define is_generic_config(x) 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /* probe individual codec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) static int hda_codec_probe(struct snd_sof_dev *sdev, int address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) bool hda_codec_use_common_hdmi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct hdac_hda_priv *hda_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) struct hda_codec *codec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) int type = HDA_DEV_LEGACY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) struct hda_bus *hbus = sof_to_hbus(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct hdac_device *hdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) u32 hda_cmd = (address << 28) | (AC_NODE_ROOT << 20) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) (AC_VERB_PARAMETERS << 8) | AC_PAR_VENDOR_ID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) u32 resp = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) mutex_lock(&hbus->core.cmd_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) snd_hdac_bus_send_cmd(&hbus->core, hda_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) snd_hdac_bus_get_response(&hbus->core, address, &resp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) mutex_unlock(&hbus->core.cmd_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) if (resp == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) dev_dbg(sdev->dev, "HDA codec #%d probed OK: response: %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) address, resp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) hda_priv = devm_kzalloc(sdev->dev, sizeof(*hda_priv), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) if (!hda_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) hda_priv->codec.bus = hbus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) hdev = &hda_priv->codec.core;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) codec = &hda_priv->codec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /* only probe ASoC codec drivers for HDAC-HDMI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) if (!hda_codec_use_common_hdmi && (resp & 0xFFFF0000) == IDISP_VID_INTEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) type = HDA_DEV_ASOC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) ret = snd_hdac_ext_bus_device_init(&hbus->core, address, hdev, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if ((resp & 0xFFFF0000) == IDISP_VID_INTEL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) if (!hdev->bus->audio_component) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) dev_dbg(sdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) "iDisp hw present but no driver\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) hda_priv->need_display_power = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (is_generic_config(hbus))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) codec->probe_id = HDA_CODEC_ID_GENERIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) codec->probe_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if (type == HDA_DEV_LEGACY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) ret = hda_codec_load_module(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * handle ret==0 (no driver bound) as an error, but pass
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) * other return codes without modification
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) snd_hdac_device_unregister(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) put_device(&hdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) hdev = devm_kzalloc(sdev->dev, sizeof(*hdev), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) if (!hdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) ret = snd_hdac_ext_bus_device_init(&hbus->core, address, hdev, HDA_DEV_ASOC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) /* Codec initialization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) void hda_codec_probe_bus(struct snd_sof_dev *sdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) bool hda_codec_use_common_hdmi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) struct hdac_bus *bus = sof_to_bus(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) /* probe codecs in avail slots */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) for (i = 0; i < HDA_MAX_CODECS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) if (!(bus->codec_mask & (1 << i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) ret = hda_codec_probe(sdev, i, hda_codec_use_common_hdmi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) dev_warn(bus->dev, "codec #%d probe error, ret: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) i, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) bus->codec_mask &= ~BIT(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) EXPORT_SYMBOL_NS(hda_codec_probe_bus, SND_SOC_SOF_HDA_AUDIO_CODEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) #if IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI) || \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) void hda_codec_i915_display_power(struct snd_sof_dev *sdev, bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) struct hdac_bus *bus = sof_to_bus(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) if (HDA_IDISP_CODEC(bus->codec_mask)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) dev_dbg(bus->dev, "Turning i915 HDAC power %d\n", enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) EXPORT_SYMBOL_NS(hda_codec_i915_display_power, SND_SOC_SOF_HDA_AUDIO_CODEC_I915);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) int hda_codec_i915_init(struct snd_sof_dev *sdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) struct hdac_bus *bus = sof_to_bus(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) /* i915 exposes a HDA codec for HDMI audio */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) ret = snd_hdac_i915_init(bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) /* codec_mask not yet known, power up for probe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) EXPORT_SYMBOL_NS(hda_codec_i915_init, SND_SOC_SOF_HDA_AUDIO_CODEC_I915);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) int hda_codec_i915_exit(struct snd_sof_dev *sdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) struct hdac_bus *bus = sof_to_bus(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) if (!bus->audio_component)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) /* power down unconditionally */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return snd_hdac_i915_exit(bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) EXPORT_SYMBOL_NS(hda_codec_i915_exit, SND_SOC_SOF_HDA_AUDIO_CODEC_I915);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) MODULE_LICENSE("Dual BSD/GPL");