Commit eef37596 authored by Stefan Binding's avatar Stefan Binding Committed by Takashi Iwai

ALSA: hda: cs35l41: Support reading subsystem id from ACPI

On some laptop models, the ACPI contains the unique
Subsystem ID, and this value should be preferred
over the value from the HDA driver.
Signed-off-by: default avatarStefan Binding <sbinding@opensource.cirrus.com>
Signed-off-by: default avatarVitaly Rodionov <vitalyr@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20220630002335.366545-7-vitalyr@opensource.cirrus.comSigned-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent e99f3c7e
......@@ -544,6 +544,36 @@ static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41)
return cs35l41_hda_channel_map(cs35l41->dev, 0, NULL, 1, &hw_cfg->spk_pos);
}
static int cs35l41_get_acpi_sub_string(struct device *dev, struct acpi_device *adev,
const char **subsysid)
{
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
union acpi_object *obj;
acpi_status status;
int ret = 0;
status = acpi_evaluate_object(adev->handle, "_SUB", NULL, &buffer);
if (ACPI_SUCCESS(status)) {
obj = buffer.pointer;
if (obj->type == ACPI_TYPE_STRING) {
*subsysid = devm_kstrdup(dev, obj->string.pointer, GFP_KERNEL);
if (*subsysid == NULL) {
dev_err(dev, "Cannot allocate Subsystem ID");
ret = -ENOMEM;
}
} else {
dev_warn(dev, "Warning ACPI _SUB did not return a string\n");
ret = -ENODEV;
}
acpi_os_free(buffer.pointer);
} else {
dev_dbg(dev, "Warning ACPI _SUB failed: %#x\n", status);
ret = -ENODEV;
}
return ret;
}
static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, int id)
{
struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg;
......@@ -563,6 +593,12 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i
physdev = get_device(acpi_get_first_physical_node(adev));
acpi_dev_put(adev);
ret = cs35l41_get_acpi_sub_string(cs35l41->dev, adev, &cs35l41->acpi_subsystem_id);
if (ret)
dev_info(cs35l41->dev, "No Subsystem ID found in ACPI: %d", ret);
else
dev_dbg(cs35l41->dev, "Subsystem ID %s found", cs35l41->acpi_subsystem_id);
property = "cirrus,dev-index";
ret = device_property_count_u32(physdev, property);
if (ret <= 0)
......
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