Commit 2f7f0994 authored by Mark Brown's avatar Mark Brown

Allow detecting ACP6x DMIC via _DSD

Merge series from Mario Limonciello <mario.limonciello@amd.com>:

It's not possible to probe for the presence of a DMIC, so the ACP6x
machine driver currently has a hardcoded list of all the systems known
to have a DMIC connected to the ACP.

Although this design works it means that the acp6x driver needs to always
grow with more systems and worse, if an OEM introduces a new system there
will be a mismatch in time that even if the driver (otherwise) works fine
it needs their system added to the list to work.

So this series introduces a _DSD that OEMs can populate into the BIOS to
indicate presence of a DMIC.
parents 31c90dd5 5426f506
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <sound/pcm_params.h> #include <sound/pcm_params.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/dmi.h> #include <linux/dmi.h>
#include <linux/acpi.h>
#include "acp6x.h" #include "acp6x.h"
...@@ -45,108 +46,126 @@ static struct snd_soc_card acp6x_card = { ...@@ -45,108 +46,126 @@ static struct snd_soc_card acp6x_card = {
static const struct dmi_system_id yc_acp_quirk_table[] = { static const struct dmi_system_id yc_acp_quirk_table[] = {
{ {
.driver_data = &acp6x_card,
.matches = { .matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_NAME, "21D2"), DMI_MATCH(DMI_PRODUCT_NAME, "21D2"),
} }
}, },
{ {
.driver_data = &acp6x_card,
.matches = { .matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_NAME, "21D3"), DMI_MATCH(DMI_PRODUCT_NAME, "21D3"),
} }
}, },
{ {
.driver_data = &acp6x_card,
.matches = { .matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_NAME, "21D4"), DMI_MATCH(DMI_PRODUCT_NAME, "21D4"),
} }
}, },
{ {
.driver_data = &acp6x_card,
.matches = { .matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_NAME, "21D5"), DMI_MATCH(DMI_PRODUCT_NAME, "21D5"),
} }
}, },
{ {
.driver_data = &acp6x_card,
.matches = { .matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_NAME, "21CF"), DMI_MATCH(DMI_PRODUCT_NAME, "21CF"),
} }
}, },
{ {
.driver_data = &acp6x_card,
.matches = { .matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_NAME, "21CG"), DMI_MATCH(DMI_PRODUCT_NAME, "21CG"),
} }
}, },
{ {
.driver_data = &acp6x_card,
.matches = { .matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_NAME, "21CQ"), DMI_MATCH(DMI_PRODUCT_NAME, "21CQ"),
} }
}, },
{ {
.driver_data = &acp6x_card,
.matches = { .matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_NAME, "21CR"), DMI_MATCH(DMI_PRODUCT_NAME, "21CR"),
} }
}, },
{ {
.driver_data = &acp6x_card,
.matches = { .matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_NAME, "21AW"), DMI_MATCH(DMI_PRODUCT_NAME, "21AW"),
} }
}, },
{ {
.driver_data = &acp6x_card,
.matches = { .matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_NAME, "21AX"), DMI_MATCH(DMI_PRODUCT_NAME, "21AX"),
} }
}, },
{ {
.driver_data = &acp6x_card,
.matches = { .matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_NAME, "21BN"), DMI_MATCH(DMI_PRODUCT_NAME, "21BN"),
} }
}, },
{ {
.driver_data = &acp6x_card,
.matches = { .matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_NAME, "21BQ"), DMI_MATCH(DMI_PRODUCT_NAME, "21BQ"),
} }
}, },
{ {
.driver_data = &acp6x_card,
.matches = { .matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_NAME, "21CH"), DMI_MATCH(DMI_PRODUCT_NAME, "21CH"),
} }
}, },
{ {
.driver_data = &acp6x_card,
.matches = { .matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_NAME, "21CJ"), DMI_MATCH(DMI_PRODUCT_NAME, "21CJ"),
} }
}, },
{ {
.driver_data = &acp6x_card,
.matches = { .matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_NAME, "21CK"), DMI_MATCH(DMI_PRODUCT_NAME, "21CK"),
} }
}, },
{ {
.driver_data = &acp6x_card,
.matches = { .matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_NAME, "21CL"), DMI_MATCH(DMI_PRODUCT_NAME, "21CL"),
} }
}, },
{ {
.driver_data = &acp6x_card,
.matches = { .matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_NAME, "21D8"), DMI_MATCH(DMI_PRODUCT_NAME, "21D8"),
} }
}, },
{ {
.driver_data = &acp6x_card,
.matches = { .matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_NAME, "21D9"), DMI_MATCH(DMI_PRODUCT_NAME, "21D9"),
...@@ -157,18 +176,33 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { ...@@ -157,18 +176,33 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
static int acp6x_probe(struct platform_device *pdev) static int acp6x_probe(struct platform_device *pdev)
{ {
const struct dmi_system_id *dmi_id;
struct acp6x_pdm *machine = NULL; struct acp6x_pdm *machine = NULL;
struct snd_soc_card *card; struct snd_soc_card *card;
struct acpi_device *adev;
int ret; int ret;
const struct dmi_system_id *dmi_id;
/* check the parent device's firmware node has _DSD or not */
adev = ACPI_COMPANION(pdev->dev.parent);
if (adev) {
const union acpi_object *obj;
if (!acpi_dev_get_property(adev, "AcpDmicConnected", ACPI_TYPE_INTEGER, &obj) &&
obj->integer.value == 1)
platform_set_drvdata(pdev, &acp6x_card);
}
/* check for any DMI overrides */
dmi_id = dmi_first_match(yc_acp_quirk_table); dmi_id = dmi_first_match(yc_acp_quirk_table);
if (!dmi_id) if (dmi_id)
platform_set_drvdata(pdev, dmi_id->driver_data);
card = platform_get_drvdata(pdev);
if (!card)
return -ENODEV; return -ENODEV;
card = &acp6x_card; dev_info(&pdev->dev, "Enabling ACP DMIC support via %s", dmi_id ? "DMI" : "ACPI");
acp6x_card.dev = &pdev->dev; acp6x_card.dev = &pdev->dev;
platform_set_drvdata(pdev, card);
snd_soc_card_set_drvdata(card, machine); snd_soc_card_set_drvdata(card, machine);
ret = devm_snd_soc_register_card(&pdev->dev, card); ret = devm_snd_soc_register_card(&pdev->dev, card);
if (ret) { if (ret) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment