Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 64e84305 authored by Pierre-Louis Bossart's avatar Pierre-Louis Bossart Committed by Mark Brown
Browse files

ASoC: Intel: detect audio routing with CHAN package



Baytrail-CR devices usually expose information in the DSDT
which can be used to auto-detect AIF1/AIF2 connections.
The CHAN package contains two integers, the first one describes
the AIF number (1: AIF1, 2: AIF2) and the second the MCLK
value (ignored in this patch)

For example the following information is found in Lenovo 100s:

Device (RTEK) {
[...]
    Name (CHAN, Package (0x02)
    {
        One,
        0x017D7840
    })

While on Asus T100TAF the package values are:

    Name (CHAN, Package (0x02)
    {
        0x02,
        0x017D7840
    })

This patch relies on the new common routine to extract
a package exposed by a device indexed with the HID value.
The CHAN package contents are queried from the machine driver
and stored in a structure.

If this auto-detection fails (missing or bad package in the
BIOS), the routing falls back to SSP0-AIF2.

Note that quirks may still be needed to support mono speakers
or microphone, but this should reduce the number of issues with
Baytrail significantly.

Signed-off-by: default avatarPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 34218947
Loading
Loading
Loading
Loading
+51 −2
Original line number Diff line number Diff line
@@ -689,6 +689,10 @@ static bool is_valleyview(void)
	return true;
}

struct acpi_chan_package {   /* ACPICA seems to require 64 bit integers */
	u64 aif_value;       /* 1: AIF1, 2: AIF2 */
	u64 mclock_value;    /* usually 25MHz (0x17d7940), ignored */
};

static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
{
@@ -698,6 +702,7 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
	int i;
	int dai_index;
	struct byt_rt5640_private *priv;
	bool is_bytcr = false;

	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_ATOMIC);
	if (!priv)
@@ -734,8 +739,52 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
		struct sst_platform_info *p_info = mach->pdata;
		const struct sst_res_info *res_info = p_info->res_info;

		/* TODO: use CHAN package info from BIOS to detect AIF1/AIF2 */
		if (res_info->acpi_ipc_irq_index == 0) {
		if (res_info->acpi_ipc_irq_index == 0)
			is_bytcr = true;
	}

	if (is_bytcr) {
		/*
		 * Baytrail CR platforms may have CHAN package in BIOS, try
		 * to find relevant routing quirk based as done on Windows
		 * platforms. We have to read the information directly from the
		 * BIOS, at this stage the card is not created and the links
		 * with the codec driver/pdata are non-existent
		 */

		struct acpi_chan_package chan_package;

		/* format specified: 2 64-bit integers */
		struct acpi_buffer format = {sizeof("NN"), "NN"};
		struct acpi_buffer state = {0, NULL};
		struct sst_acpi_package_context pkg_ctx;
		bool pkg_found = false;

		state.length = sizeof(chan_package);
		state.pointer = &chan_package;

		pkg_ctx.name = "CHAN";
		pkg_ctx.length = 2;
		pkg_ctx.format = &format;
		pkg_ctx.state = &state;
		pkg_ctx.data_valid = false;

		pkg_found = sst_acpi_find_package_from_hid(mach->id, &pkg_ctx);
		if (pkg_found) {
			if (chan_package.aif_value == 1) {
				dev_info(&pdev->dev, "BIOS Routing: AIF1 connected\n");
				byt_rt5640_quirk |= BYT_RT5640_SSP0_AIF1;
			} else  if (chan_package.aif_value == 2) {
				dev_info(&pdev->dev, "BIOS Routing: AIF2 connected\n");
				byt_rt5640_quirk |= BYT_RT5640_SSP0_AIF2;
			} else {
				dev_info(&pdev->dev, "BIOS Routing isn't valid, ignored\n");
				pkg_found = false;
			}
		}

		if (!pkg_found) {
			/* no BIOS indications, assume SSP0-AIF2 connection */
			byt_rt5640_quirk |= BYT_RT5640_SSP0_AIF2;
		}
	}