Unverified Commit ad850421 authored by Mark Brown's avatar Mark Brown
Browse files

ASoC: SOF: Intel: HDA: refactor codec and multi-link suport

Merge series from Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>:

Existing HDaudio controllers expose an HDAudio DMA which is used to
interface with HDaudio codecs. All other interfaces supported by Intel
(SoundWire, SSP, DMIC) rely for data transfers on another GP-DMA
managed by the DSP firmware - the HDaudio DMA is only used for
memory-to-DSP transfers.

New HDaudio extensions will enable the use of this HDaudio DMA for all
of SoundWire, SSP, DMIC. These extensions will be backwards-compatible
for HDaudio and iDISP codecs, but will require new programming
sequences and DAI callbacks for SoundWire, SSP and DMIC.

Before we add support for 'extended audio links' and the programming
sequences for the DMA, we need to refactor the code. All HDaudio codec
support needs to be well identified in a separate file, and likewise
all the 'multi-link' handling needs to be better split.

This patchset removes a number of 'old' Kconfig dependencies and
options, adds helpers with a fallback to remove IS_ENABLED checks in
the code and tries to simplify programming sequences when possible.

One indirect benefit from this refactoring is that developers can
switch with a kernel parameter from HDaudio support to a variant of
'nocodec' support. This proves extremely useful to test on existing
Intel RVPs and Up boards, where the same build can be used to check 3
interfaces (HDaudio, SSP, DMIC) by just removing modules, setting the
kernel parameter and reloading modules.
parents 3bcca378 4bd1adb8
Loading
Loading
Loading
Loading
+16 −2
Original line number Diff line number Diff line
@@ -97,13 +97,13 @@ config SND_SOC_SOF_NOCODEC
	tristate

config SND_SOC_SOF_NOCODEC_SUPPORT
	bool "SOF nocodec mode support"
	bool "SOF nocodec static mode support"
	help
	  This adds support for a dummy/nocodec machine driver fallback
	  option if no known codec is detected. This is typically only
	  enabled for developers or devices where the sound card is
	  controlled externally.
	  This option is mutually exclusive with the Intel HDAudio support.
	  This option is mutually exclusive at build time with the Intel HDAudio support.
	  Selecting it may have negative impacts and prevent e.g. microphone
	  functionality from being enabled on Intel CoffeeLake and later
	  platforms.
@@ -136,6 +136,19 @@ config SND_SOC_SOF_DEBUG

if SND_SOC_SOF_DEBUG

config SND_SOC_SOF_NOCODEC_DEBUG_SUPPORT
	bool "SOF nocodec debug mode support"
	depends on !SND_SOC_SOF_NOCODEC_SUPPORT
	help
	  This adds support for a dummy/nocodec machine driver fallback
	  option.
	  Unlike the SND_SOC_SOF_NOCODEC_SUPPORT, this option is NOT
	  mutually exclusive at build with the Intel HDAudio support. The
	  selection will be done depending on command line or modprobe.d settings
	  Distributions should not select this option!
	  Say Y if you need this nocodec debug fallback option.
	  If unsure select "N".

config SND_SOC_SOF_FORCE_NOCODEC_MODE
	bool "SOF force nocodec Mode"
	depends on SND_SOC_SOF_NOCODEC_SUPPORT
@@ -239,6 +252,7 @@ config SND_SOC_SOF
	tristate
	select SND_SOC_TOPOLOGY
	select SND_SOC_SOF_NOCODEC if SND_SOC_SOF_NOCODEC_SUPPORT
	select SND_SOC_SOF_NOCODEC if SND_SOC_SOF_NOCODEC_DEBUG_SUPPORT
	help
	  This option is not user-selectable but automagically handled by
	  'select' statements at a higher level.
+1 −1
Original line number Diff line number Diff line
@@ -277,7 +277,7 @@ if SND_SOC_SOF_HDA_COMMON

config SND_SOC_SOF_HDA_LINK
	bool "SOF support for HDA Links(HDA/HDMI)"
	depends on SND_SOC_SOF_NOCODEC=n
	depends on SND_SOC_SOF_NOCODEC_SUPPORT=n
	select SND_SOC_SOF_PROBE_WORK_QUEUE
	help
	  This adds support for HDA links(HDA/HDMI) with Sound Open Firmware
+1 −1
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@ snd-sof-acpi-intel-bdw-objs := bdw.o

snd-sof-intel-hda-common-objs := hda.o hda-loader.o hda-stream.o hda-trace.o \
				 hda-dsp.o hda-ipc.o hda-ctrl.o hda-pcm.o \
				 hda-dai.o hda-bus.o \
				 hda-dai.o hda-bus.o hda-mlink.o \
				 skl.o hda-loader-skl.o \
				 apl.o cnl.o tgl.o icl.o mtl.o hda-common-ops.o

+15 −8
Original line number Diff line number Diff line
@@ -18,11 +18,7 @@
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC)
#include "../../codecs/hdac_hda.h"
#define sof_hda_ext_ops	snd_soc_hdac_hda_get_ops()
#else
#define sof_hda_ext_ops	NULL
#endif

#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
static void update_codec_wake_enable(struct hdac_bus *bus, unsigned int addr, bool link_power)
{
	unsigned int mask = snd_hdac_chip_readw(bus, WAKEEN);
@@ -70,11 +66,13 @@ static const struct hdac_bus_ops bus_core_ops = {
/*
 * This can be used for both with/without hda link support.
 */
void sof_hda_bus_init(struct hdac_bus *bus, struct device *dev)
void sof_hda_bus_init(struct snd_sof_dev *sdev, struct device *dev)
{
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
	struct hdac_bus *bus = sof_to_bus(sdev);

#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC)
	snd_hdac_ext_bus_init(bus, dev, &bus_core_ops, sof_hda_ext_ops);
#else /* CONFIG_SND_SOC_SOF_HDA */
#else /* CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC */
	memset(bus, 0, sizeof(*bus));
	bus->dev = dev;

@@ -89,5 +87,14 @@ void sof_hda_bus_init(struct hdac_bus *bus, struct device *dev)
	bus->idx = 0;

	spin_lock_init(&bus->reg_lock);
#endif /* CONFIG_SND_SOC_SOF_HDA */
#endif /* CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC */
}

void sof_hda_bus_exit(struct snd_sof_dev *sdev)
{
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC)
	struct hdac_bus *bus = sof_to_bus(sdev);

	snd_hdac_ext_bus_exit(bus);
#endif
}
+207 −45
Original line number Diff line number Diff line
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
//
// This file is provided under a dual BSD/GPLv2 license.  When using or
// redistributing this file, you may do so under either license.
// SPDX-License-Identifier: GPL-2.0-only
//
// Copyright(c) 2018 Intel Corporation. All rights reserved.
//
@@ -16,15 +13,18 @@
#include <sound/sof.h>
#include "../ops.h"
#include "hda.h"

#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC)
#include "../../codecs/hdac_hda.h"
#endif /* CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC */

#define CODEC_PROBE_RETRIES	3

#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC)
#define IDISP_VID_INTEL	0x80860000

static int hda_codec_mask = -1;
module_param_named(codec_mask, hda_codec_mask, int, 0444);
MODULE_PARM_DESC(codec_mask, "SOF HDA codec mask for probing");

/* load the legacy HDA codec driver */
static int request_codec_module(struct hda_codec *codec)
{
@@ -72,6 +72,10 @@ void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev, bool enable)
	struct hda_codec *codec;
	unsigned int mask = 0;

	if (IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC_DEBUG_SUPPORT) &&
	    sof_debug_check_flag(SOF_DBG_FORCE_NOCODEC))
		return;

	if (enable) {
		list_for_each_codec(codec, hbus)
			if (codec->jacktbl.used)
@@ -80,6 +84,7 @@ void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev, bool enable)

	snd_hdac_chip_updatew(bus, WAKEEN, STATESTS_INT_MASK, mask);
}
EXPORT_SYMBOL_NS_GPL(hda_codec_jack_wake_enable, SND_SOC_SOF_HDA_AUDIO_CODEC);

/* check jack status after resuming from suspend mode */
void hda_codec_jack_check(struct snd_sof_dev *sdev)
@@ -87,6 +92,10 @@ void hda_codec_jack_check(struct snd_sof_dev *sdev)
	struct hda_bus *hbus = sof_to_hbus(sdev);
	struct hda_codec *codec;

	if (IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC_DEBUG_SUPPORT) &&
	    sof_debug_check_flag(SOF_DBG_FORCE_NOCODEC))
		return;

	list_for_each_codec(codec, hbus)
		/*
		 * Wake up all jack-detecting codecs regardless whether an event
@@ -95,12 +104,7 @@ void hda_codec_jack_check(struct snd_sof_dev *sdev)
		if (codec->jacktbl.used)
			pm_request_resume(&codec->core.dev);
}
#else
void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev, bool enable) {}
void hda_codec_jack_check(struct snd_sof_dev *sdev) {}
#endif /* CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC */
EXPORT_SYMBOL_NS(hda_codec_jack_wake_enable, SND_SOC_SOF_HDA_AUDIO_CODEC);
EXPORT_SYMBOL_NS(hda_codec_jack_check, SND_SOC_SOF_HDA_AUDIO_CODEC);
EXPORT_SYMBOL_NS_GPL(hda_codec_jack_check, SND_SOC_SOF_HDA_AUDIO_CODEC);

#if IS_ENABLED(CONFIG_SND_HDA_GENERIC)
#define is_generic_config(bus) \
@@ -139,13 +143,9 @@ static struct hda_codec *hda_codec_device_init(struct hdac_bus *bus, int addr, i
}

/* probe individual codec */
static int hda_codec_probe(struct snd_sof_dev *sdev, int address,
			   bool hda_codec_use_common_hdmi)
static int hda_codec_probe(struct snd_sof_dev *sdev, int address)
{
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC)
	struct hdac_hda_priv *hda_priv;
	int type = HDA_DEV_LEGACY;
#endif
	struct hda_bus *hbus = sof_to_hbus(sdev);
	struct hda_codec *codec;
	u32 hda_cmd = (address << 28) | (AC_NODE_ROOT << 20) |
@@ -165,16 +165,11 @@ static int hda_codec_probe(struct snd_sof_dev *sdev, int address,
	dev_dbg(sdev->dev, "HDA codec #%d probed OK: response: %x\n",
		address, resp);

#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC)
	hda_priv = devm_kzalloc(sdev->dev, sizeof(*hda_priv), GFP_KERNEL);
	if (!hda_priv)
		return -ENOMEM;

	/* only probe ASoC codec drivers for HDAC-HDMI */
	if (!hda_codec_use_common_hdmi && (resp & 0xFFFF0000) == IDISP_VID_INTEL)
		type = HDA_DEV_ASOC;

	codec = hda_codec_device_init(&hbus->core, address, type);
	codec = hda_codec_device_init(&hbus->core, address, HDA_DEV_LEGACY);
	ret = PTR_ERR_OR_ZERO(codec);
	if (ret < 0)
		return ret;
@@ -197,7 +192,6 @@ static int hda_codec_probe(struct snd_sof_dev *sdev, int address,
	else
		codec->probe_id = 0;

	if (type == HDA_DEV_LEGACY) {
	ret = hda_codec_load_module(codec);
	/*
	 * handle ret==0 (no driver bound) as an error, but pass
@@ -205,35 +199,33 @@ static int hda_codec_probe(struct snd_sof_dev *sdev, int address,
	 */
	if (ret == 0)
		ret = -ENOENT;
	}

out:
	if (ret < 0) {
		snd_hdac_device_unregister(&codec->core);
		put_device(&codec->core.dev);
	}
#else
	codec = hda_codec_device_init(&hbus->core, address, HDA_DEV_ASOC);
	ret = PTR_ERR_OR_ZERO(codec);
#endif

	return ret;
}

/* Codec initialization */
void hda_codec_probe_bus(struct snd_sof_dev *sdev,
			 bool hda_codec_use_common_hdmi)
void hda_codec_probe_bus(struct snd_sof_dev *sdev)
{
	struct hdac_bus *bus = sof_to_bus(sdev);
	int i, ret;

	if (IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC_DEBUG_SUPPORT) &&
	    sof_debug_check_flag(SOF_DBG_FORCE_NOCODEC))
		return;

	/* probe codecs in avail slots */
	for (i = 0; i < HDA_MAX_CODECS; i++) {

		if (!(bus->codec_mask & (1 << i)))
			continue;

		ret = hda_codec_probe(sdev, i, hda_codec_use_common_hdmi);
		ret = hda_codec_probe(sdev, i);
		if (ret < 0) {
			dev_warn(bus->dev, "codec #%d probe error, ret: %d\n",
				 i, ret);
@@ -241,27 +233,193 @@ void hda_codec_probe_bus(struct snd_sof_dev *sdev,
		}
	}
}
EXPORT_SYMBOL_NS(hda_codec_probe_bus, SND_SOC_SOF_HDA_AUDIO_CODEC);
EXPORT_SYMBOL_NS_GPL(hda_codec_probe_bus, SND_SOC_SOF_HDA_AUDIO_CODEC);

#if IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI) || \
	IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)
void hda_codec_check_for_state_change(struct snd_sof_dev *sdev)
{
	struct hdac_bus *bus = sof_to_bus(sdev);
	unsigned int codec_mask;

	codec_mask = snd_hdac_chip_readw(bus, STATESTS);
	if (codec_mask) {
		hda_codec_jack_check(sdev);
		snd_hdac_chip_writew(bus, STATESTS, codec_mask);
	}
}
EXPORT_SYMBOL_NS_GPL(hda_codec_check_for_state_change, SND_SOC_SOF_HDA_AUDIO_CODEC);

void hda_codec_detect_mask(struct snd_sof_dev *sdev)
{
	struct hdac_bus *bus = sof_to_bus(sdev);

	if (IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC_DEBUG_SUPPORT) &&
	    sof_debug_check_flag(SOF_DBG_FORCE_NOCODEC))
		return;

	/* Accept unsolicited responses */
	snd_hdac_chip_updatel(bus, GCTL, AZX_GCTL_UNSOL, AZX_GCTL_UNSOL);

	/* detect codecs */
	if (!bus->codec_mask) {
		bus->codec_mask = snd_hdac_chip_readw(bus, STATESTS);
		dev_dbg(bus->dev, "codec_mask = 0x%lx\n", bus->codec_mask);
	}

	if (hda_codec_mask != -1) {
		bus->codec_mask &= hda_codec_mask;
		dev_dbg(bus->dev, "filtered codec_mask = 0x%lx\n",
			bus->codec_mask);
	}
}
EXPORT_SYMBOL_NS_GPL(hda_codec_detect_mask, SND_SOC_SOF_HDA_AUDIO_CODEC);

void hda_codec_init_cmd_io(struct snd_sof_dev *sdev)
{
	struct hdac_bus *bus = sof_to_bus(sdev);

	if (IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC_DEBUG_SUPPORT) &&
	    sof_debug_check_flag(SOF_DBG_FORCE_NOCODEC))
		return;

	/* initialize the codec command I/O */
	snd_hdac_bus_init_cmd_io(bus);
}
EXPORT_SYMBOL_NS_GPL(hda_codec_init_cmd_io, SND_SOC_SOF_HDA_AUDIO_CODEC);

void hda_codec_resume_cmd_io(struct snd_sof_dev *sdev)
{
	struct hdac_bus *bus = sof_to_bus(sdev);

	if (IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC_DEBUG_SUPPORT) &&
	    sof_debug_check_flag(SOF_DBG_FORCE_NOCODEC))
		return;

	/* set up CORB/RIRB buffers if was on before suspend */
	if (bus->cmd_dma_state)
		snd_hdac_bus_init_cmd_io(bus);
}
EXPORT_SYMBOL_NS_GPL(hda_codec_resume_cmd_io, SND_SOC_SOF_HDA_AUDIO_CODEC);

void hda_codec_stop_cmd_io(struct snd_sof_dev *sdev)
{
	struct hdac_bus *bus = sof_to_bus(sdev);

	if (IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC_DEBUG_SUPPORT) &&
	    sof_debug_check_flag(SOF_DBG_FORCE_NOCODEC))
		return;

	/* initialize the codec command I/O */
	snd_hdac_bus_stop_cmd_io(bus);
}
EXPORT_SYMBOL_NS_GPL(hda_codec_stop_cmd_io, SND_SOC_SOF_HDA_AUDIO_CODEC);

void hda_codec_suspend_cmd_io(struct snd_sof_dev *sdev)
{
	struct hdac_bus *bus = sof_to_bus(sdev);

	if (IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC_DEBUG_SUPPORT) &&
	    sof_debug_check_flag(SOF_DBG_FORCE_NOCODEC))
		return;

	/* stop the CORB/RIRB DMA if it is On */
	if (bus->cmd_dma_state)
		snd_hdac_bus_stop_cmd_io(bus);

}
EXPORT_SYMBOL_NS_GPL(hda_codec_suspend_cmd_io, SND_SOC_SOF_HDA_AUDIO_CODEC);

void hda_codec_rirb_status_clear(struct snd_sof_dev *sdev)
{
	struct hdac_bus *bus = sof_to_bus(sdev);

	if (IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC_DEBUG_SUPPORT) &&
	    sof_debug_check_flag(SOF_DBG_FORCE_NOCODEC))
		return;

	/* clear rirb status */
	snd_hdac_chip_writeb(bus, RIRBSTS, RIRB_INT_MASK);
}
EXPORT_SYMBOL_NS_GPL(hda_codec_rirb_status_clear, SND_SOC_SOF_HDA_AUDIO_CODEC);

void hda_codec_set_codec_wakeup(struct snd_sof_dev *sdev, bool status)
{
	struct hdac_bus *bus = sof_to_bus(sdev);

	if (sof_debug_check_flag(SOF_DBG_FORCE_NOCODEC))
		return;

	snd_hdac_set_codec_wakeup(bus, status);
}
EXPORT_SYMBOL_NS_GPL(hda_codec_set_codec_wakeup, SND_SOC_SOF_HDA_AUDIO_CODEC);

bool hda_codec_check_rirb_status(struct snd_sof_dev *sdev)
{
	struct hdac_bus *bus = sof_to_bus(sdev);
	bool active = false;
	u32 rirb_status;

	if (IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC_DEBUG_SUPPORT) &&
	    sof_debug_check_flag(SOF_DBG_FORCE_NOCODEC))
		return false;

	rirb_status = snd_hdac_chip_readb(bus, RIRBSTS);
	if (rirb_status & RIRB_INT_MASK) {
		/*
		 * Clearing the interrupt status here ensures
		 * that no interrupt gets masked after the RIRB
		 * wp is read in snd_hdac_bus_update_rirb.
		 */
		snd_hdac_chip_writeb(bus, RIRBSTS,
				     RIRB_INT_MASK);
		active = true;
		if (rirb_status & RIRB_INT_RESPONSE)
			snd_hdac_bus_update_rirb(bus);
	}
	return active;
}
EXPORT_SYMBOL_NS_GPL(hda_codec_check_rirb_status, SND_SOC_SOF_HDA_AUDIO_CODEC);

void hda_codec_device_remove(struct snd_sof_dev *sdev)
{
	struct hdac_bus *bus = sof_to_bus(sdev);

	if (IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC_DEBUG_SUPPORT) &&
	    sof_debug_check_flag(SOF_DBG_FORCE_NOCODEC))
		return;

	/* codec removal, invoke bus_device_remove */
	snd_hdac_ext_bus_device_remove(bus);
}
EXPORT_SYMBOL_NS_GPL(hda_codec_device_remove, SND_SOC_SOF_HDA_AUDIO_CODEC);

#endif /* CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC */

#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) && IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI)

void hda_codec_i915_display_power(struct snd_sof_dev *sdev, bool enable)
{
	struct hdac_bus *bus = sof_to_bus(sdev);

	if (IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC_DEBUG_SUPPORT) &&
	    sof_debug_check_flag(SOF_DBG_FORCE_NOCODEC))
		return;

	if (HDA_IDISP_CODEC(bus->codec_mask)) {
		dev_dbg(bus->dev, "Turning i915 HDAC power %d\n", enable);
		snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, enable);
	}
}
EXPORT_SYMBOL_NS(hda_codec_i915_display_power, SND_SOC_SOF_HDA_AUDIO_CODEC_I915);
EXPORT_SYMBOL_NS_GPL(hda_codec_i915_display_power, SND_SOC_SOF_HDA_AUDIO_CODEC_I915);

int hda_codec_i915_init(struct snd_sof_dev *sdev)
{
	struct hdac_bus *bus = sof_to_bus(sdev);
	int ret;

	if (IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC_DEBUG_SUPPORT) &&
	    sof_debug_check_flag(SOF_DBG_FORCE_NOCODEC))
		return 0;

	/* i915 exposes a HDA codec for HDMI audio */
	ret = snd_hdac_i915_init(bus);
	if (ret < 0)
@@ -272,12 +430,16 @@ int hda_codec_i915_init(struct snd_sof_dev *sdev)

	return 0;
}
EXPORT_SYMBOL_NS(hda_codec_i915_init, SND_SOC_SOF_HDA_AUDIO_CODEC_I915);
EXPORT_SYMBOL_NS_GPL(hda_codec_i915_init, SND_SOC_SOF_HDA_AUDIO_CODEC_I915);

int hda_codec_i915_exit(struct snd_sof_dev *sdev)
{
	struct hdac_bus *bus = sof_to_bus(sdev);

	if (IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC_DEBUG_SUPPORT) &&
	    sof_debug_check_flag(SOF_DBG_FORCE_NOCODEC))
		return 0;

	if (!bus->audio_component)
		return 0;

@@ -286,7 +448,7 @@ int hda_codec_i915_exit(struct snd_sof_dev *sdev)

	return snd_hdac_i915_exit(bus);
}
EXPORT_SYMBOL_NS(hda_codec_i915_exit, SND_SOC_SOF_HDA_AUDIO_CODEC_I915);
EXPORT_SYMBOL_NS_GPL(hda_codec_i915_exit, SND_SOC_SOF_HDA_AUDIO_CODEC_I915);

#endif

Loading