Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Stefan Binding <sbinding@opensource.cirrus.com>
Signed-off-by: Vitaly Rodionov <vitalyr@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20220630002335.366545-7-vitalyr@opensource.cirrus.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>

authored by

Stefan Binding and committed by
Takashi Iwai
eef37596 e99f3c7e

+36
+36
sound/pci/hda/cs35l41_hda.c
··· 544 544 return cs35l41_hda_channel_map(cs35l41->dev, 0, NULL, 1, &hw_cfg->spk_pos); 545 545 } 546 546 547 + static int cs35l41_get_acpi_sub_string(struct device *dev, struct acpi_device *adev, 548 + const char **subsysid) 549 + { 550 + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 551 + union acpi_object *obj; 552 + acpi_status status; 553 + int ret = 0; 554 + 555 + status = acpi_evaluate_object(adev->handle, "_SUB", NULL, &buffer); 556 + if (ACPI_SUCCESS(status)) { 557 + obj = buffer.pointer; 558 + if (obj->type == ACPI_TYPE_STRING) { 559 + *subsysid = devm_kstrdup(dev, obj->string.pointer, GFP_KERNEL); 560 + if (*subsysid == NULL) { 561 + dev_err(dev, "Cannot allocate Subsystem ID"); 562 + ret = -ENOMEM; 563 + } 564 + } else { 565 + dev_warn(dev, "Warning ACPI _SUB did not return a string\n"); 566 + ret = -ENODEV; 567 + } 568 + acpi_os_free(buffer.pointer); 569 + } else { 570 + dev_dbg(dev, "Warning ACPI _SUB failed: %#x\n", status); 571 + ret = -ENODEV; 572 + } 573 + 574 + return ret; 575 + } 576 + 547 577 static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, int id) 548 578 { 549 579 struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg; ··· 592 562 593 563 physdev = get_device(acpi_get_first_physical_node(adev)); 594 564 acpi_dev_put(adev); 565 + 566 + ret = cs35l41_get_acpi_sub_string(cs35l41->dev, adev, &cs35l41->acpi_subsystem_id); 567 + if (ret) 568 + dev_info(cs35l41->dev, "No Subsystem ID found in ACPI: %d", ret); 569 + else 570 + dev_dbg(cs35l41->dev, "Subsystem ID %s found", cs35l41->acpi_subsystem_id); 595 571 596 572 property = "cirrus,dev-index"; 597 573 ret = device_property_count_u32(physdev, property);