Takashi Iwai 7199b5
From eef375960210fdc1ec2786bddc91ff100444ffb8 Mon Sep 17 00:00:00 2001
Takashi Iwai 7199b5
From: Stefan Binding <sbinding@opensource.cirrus.com>
Takashi Iwai 7199b5
Date: Thu, 30 Jun 2022 01:23:27 +0100
Takashi Iwai 7199b5
Subject: [PATCH] ALSA: hda: cs35l41: Support reading subsystem id from ACPI
Takashi Iwai 7199b5
Git-commit: eef375960210fdc1ec2786bddc91ff100444ffb8
Takashi Iwai 7199b5
Patch-mainline: v6.0-rc1
Takashi Iwai 7199b5
References: bsc#1203699
Takashi Iwai 7199b5
Takashi Iwai 7199b5
On some laptop models, the ACPI contains the unique
Takashi Iwai 7199b5
Subsystem ID, and this value should be preferred
Takashi Iwai 7199b5
over the value from the HDA driver.
Takashi Iwai 7199b5
Takashi Iwai 7199b5
Signed-off-by: Stefan Binding <sbinding@opensource.cirrus.com>
Takashi Iwai 7199b5
Signed-off-by: Vitaly Rodionov <vitalyr@opensource.cirrus.com>
Takashi Iwai 7199b5
Link: https://lore.kernel.org/r/20220630002335.366545-7-vitalyr@opensource.cirrus.com
Takashi Iwai 7199b5
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Takashi Iwai 7199b5
Takashi Iwai 7199b5
---
Takashi Iwai 7199b5
 sound/pci/hda/cs35l41_hda.c | 36 ++++++++++++++++++++++++++++++++++++
Takashi Iwai 7199b5
 1 file changed, 36 insertions(+)
Takashi Iwai 7199b5
Takashi Iwai 7199b5
diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c
Takashi Iwai 7199b5
index 25cb76437ba5..effb3ce95c00 100644
Takashi Iwai 7199b5
--- a/sound/pci/hda/cs35l41_hda.c
Takashi Iwai 7199b5
+++ b/sound/pci/hda/cs35l41_hda.c
Takashi Iwai 7199b5
@@ -544,6 +544,36 @@ static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41)
Takashi Iwai 7199b5
 	return cs35l41_hda_channel_map(cs35l41->dev, 0, NULL, 1, &hw_cfg->spk_pos);
Takashi Iwai 7199b5
 }
Takashi Iwai 7199b5
 
Takashi Iwai 7199b5
+static int cs35l41_get_acpi_sub_string(struct device *dev, struct acpi_device *adev,
Takashi Iwai 7199b5
+				       const char **subsysid)
Takashi Iwai 7199b5
+{
Takashi Iwai 7199b5
+	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
Takashi Iwai 7199b5
+	union acpi_object *obj;
Takashi Iwai 7199b5
+	acpi_status status;
Takashi Iwai 7199b5
+	int ret = 0;
Takashi Iwai 7199b5
+
Takashi Iwai 7199b5
+	status = acpi_evaluate_object(adev->handle, "_SUB", NULL, &buffer);
Takashi Iwai 7199b5
+	if (ACPI_SUCCESS(status)) {
Takashi Iwai 7199b5
+		obj = buffer.pointer;
Takashi Iwai 7199b5
+		if (obj->type == ACPI_TYPE_STRING) {
Takashi Iwai 7199b5
+			*subsysid = devm_kstrdup(dev, obj->string.pointer, GFP_KERNEL);
Takashi Iwai 7199b5
+			if (*subsysid == NULL) {
Takashi Iwai 7199b5
+				dev_err(dev, "Cannot allocate Subsystem ID");
Takashi Iwai 7199b5
+				ret = -ENOMEM;
Takashi Iwai 7199b5
+			}
Takashi Iwai 7199b5
+		} else {
Takashi Iwai 7199b5
+			dev_warn(dev, "Warning ACPI _SUB did not return a string\n");
Takashi Iwai 7199b5
+			ret = -ENODEV;
Takashi Iwai 7199b5
+		}
Takashi Iwai 7199b5
+		acpi_os_free(buffer.pointer);
Takashi Iwai 7199b5
+	} else {
Takashi Iwai 7199b5
+		dev_dbg(dev, "Warning ACPI _SUB failed: %#x\n", status);
Takashi Iwai 7199b5
+		ret = -ENODEV;
Takashi Iwai 7199b5
+	}
Takashi Iwai 7199b5
+
Takashi Iwai 7199b5
+	return ret;
Takashi Iwai 7199b5
+}
Takashi Iwai 7199b5
+
Takashi Iwai 7199b5
 static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, int id)
Takashi Iwai 7199b5
 {
Takashi Iwai 7199b5
 	struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg;
Takashi Iwai 7199b5
@@ -563,6 +593,12 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i
Takashi Iwai 7199b5
 	physdev = get_device(acpi_get_first_physical_node(adev));
Takashi Iwai 7199b5
 	acpi_dev_put(adev);
Takashi Iwai 7199b5
 
Takashi Iwai 7199b5
+	ret = cs35l41_get_acpi_sub_string(cs35l41->dev, adev, &cs35l41->acpi_subsystem_id);
Takashi Iwai 7199b5
+	if (ret)
Takashi Iwai 7199b5
+		dev_info(cs35l41->dev, "No Subsystem ID found in ACPI: %d", ret);
Takashi Iwai 7199b5
+	else
Takashi Iwai 7199b5
+		dev_dbg(cs35l41->dev, "Subsystem ID %s found", cs35l41->acpi_subsystem_id);
Takashi Iwai 7199b5
+
Takashi Iwai 7199b5
 	property = "cirrus,dev-index";
Takashi Iwai 7199b5
 	ret = device_property_count_u32(physdev, property);
Takashi Iwai 7199b5
 	if (ret <= 0)
Takashi Iwai 7199b5
-- 
Takashi Iwai 7199b5
2.35.3
Takashi Iwai 7199b5