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>
This commit is contained in:
Родитель
e99f3c7e32
Коммит
eef3759602
|
@ -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)
|
||||
|
|
Загрузка…
Ссылка в новой задаче