aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/intel/skylake/skl.c
diff options
context:
space:
mode:
authorRakesh Ughreja <rakesh.a.ughreja@intel.com>2018-08-22 15:25:03 -0500
committerMark Brown <broonie@kernel.org>2018-08-28 20:18:13 +0100
commit6bae5ea9498926440ffc883f3dbceb0adc65e492 (patch)
tree28f83dda3f2da9a5ff333fbd1675dbd5f186ba88 /sound/soc/intel/skylake/skl.c
parentASoC: Intel: Skylake: use hda_bus instead of hdac_bus (diff)
downloadlinux-dev-6bae5ea9498926440ffc883f3dbceb0adc65e492.tar.xz
linux-dev-6bae5ea9498926440ffc883f3dbceb0adc65e492.zip
ASoC: hdac_hda: add asoc extension for legacy HDA codec drivers
This patch adds a kernel module which is used by the legacy HDA codec drivers as library. This implements hdac_ext_bus_ops to enable the reuse of legacy HDA codec drivers with ASoC platform drivers. Signed-off-by: Rakesh Ughreja <rakesh.a.ughreja@intel.com> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/intel/skylake/skl.c')
-rw-r--r--sound/soc/intel/skylake/skl.c47
1 files changed, 43 insertions, 4 deletions
diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c
index 5f281d443a53..e7fd14daeb4f 100644
--- a/sound/soc/intel/skylake/skl.c
+++ b/sound/soc/intel/skylake/skl.c
@@ -37,6 +37,7 @@
#include "skl.h"
#include "skl-sst-dsp.h"
#include "skl-sst-ipc.h"
+#include "../../../soc/codecs/hdac_hda.h"
/*
* initialize the PCI registers
@@ -657,6 +658,24 @@ static void skl_clock_device_unregister(struct skl *skl)
platform_device_unregister(skl->clk_dev);
}
+#define IDISP_INTEL_VENDOR_ID 0x80860000
+
+/*
+ * load the legacy codec driver
+ */
+static void load_codec_module(struct hda_codec *codec)
+{
+#ifdef MODULE
+ char modalias[MODULE_NAME_LEN];
+ const char *mod = NULL;
+
+ snd_hdac_codec_modalias(&codec->core, modalias, sizeof(modalias));
+ mod = modalias;
+ dev_dbg(&codec->core.dev, "loading %s codec module\n", mod);
+ request_module(mod);
+#endif
+}
+
/*
* Probe the given codec address
*/
@@ -666,7 +685,9 @@ static int probe_codec(struct hdac_bus *bus, int addr)
(AC_VERB_PARAMETERS << 8) | AC_PAR_VENDOR_ID;
unsigned int res = -1;
struct skl *skl = bus_to_skl(bus);
+ struct hdac_hda_priv *hda_codec;
struct hdac_device *hdev;
+ int err;
mutex_lock(&bus->cmd_mutex);
snd_hdac_bus_send_cmd(bus, cmd);
@@ -676,11 +697,24 @@ static int probe_codec(struct hdac_bus *bus, int addr)
return -EIO;
dev_dbg(bus->dev, "codec #%d probed OK: %x\n", addr, res);
- hdev = devm_kzalloc(&skl->pci->dev, sizeof(*hdev), GFP_KERNEL);
- if (!hdev)
+ hda_codec = devm_kzalloc(&skl->pci->dev, sizeof(*hda_codec),
+ GFP_KERNEL);
+ if (!hda_codec)
return -ENOMEM;
- return snd_hdac_ext_bus_device_init(bus, addr, hdev);
+ hda_codec->codec.bus = skl_to_hbus(skl);
+ hdev = &hda_codec->codec.core;
+
+ err = snd_hdac_ext_bus_device_init(bus, addr, hdev);
+ if (err < 0)
+ return err;
+
+ /* use legacy bus only for HDA codecs, idisp uses ext bus */
+ if ((res & 0xFFFF0000) != IDISP_INTEL_VENDOR_ID) {
+ hdev->type = HDA_DEV_LEGACY;
+ load_codec_module(&hda_codec->codec);
+ }
+ return 0;
}
/* Codec initialization */
@@ -815,6 +849,7 @@ static int skl_create(struct pci_dev *pci,
const struct hdac_io_ops *io_ops,
struct skl **rskl)
{
+ struct hdac_ext_bus_ops *ext_ops = NULL;
struct skl *skl;
struct hdac_bus *bus;
struct hda_bus *hbus;
@@ -834,7 +869,11 @@ static int skl_create(struct pci_dev *pci,
hbus = skl_to_hbus(skl);
bus = skl_to_bus(skl);
- snd_hdac_ext_bus_init(bus, &pci->dev, &bus_core_ops, io_ops, NULL);
+
+#if IS_ENABLED(CONFIG_SND_SOC_HDAC_HDA)
+ ext_ops = snd_soc_hdac_hda_get_ops();
+#endif
+ snd_hdac_ext_bus_init(bus, &pci->dev, &bus_core_ops, io_ops, ext_ops);
bus->use_posbuf = 1;
skl->pci = pci;
INIT_WORK(&skl->probe_work, skl_probe_work);