1 // SPDX-License-Identifier: GPL-2.0 2 // 3 // soc-apci.c - support for ACPI enumeration. 4 // 5 // Copyright (c) 2013-15, Intel Corporation. 6 7 #include <sound/soc-acpi.h> 8 9 struct snd_soc_acpi_mach * 10 snd_soc_acpi_find_machine(struct snd_soc_acpi_mach *machines) 11 { 12 struct snd_soc_acpi_mach *mach; 13 14 for (mach = machines; mach->id[0]; mach++) { 15 if (acpi_dev_present(mach->id, NULL, -1)) { 16 if (mach->machine_quirk) 17 mach = mach->machine_quirk(mach); 18 return mach; 19 } 20 } 21 return NULL; 22 } 23 EXPORT_SYMBOL_GPL(snd_soc_acpi_find_machine); 24 25 static acpi_status snd_soc_acpi_find_package(acpi_handle handle, u32 level, 26 void *context, void **ret) 27 { 28 struct acpi_device *adev; 29 acpi_status status = AE_OK; 30 struct snd_soc_acpi_package_context *pkg_ctx = context; 31 32 pkg_ctx->data_valid = false; 33 34 if (acpi_bus_get_device(handle, &adev)) 35 return AE_OK; 36 37 if (adev->status.present && adev->status.functional) { 38 struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; 39 union acpi_object *myobj = NULL; 40 41 status = acpi_evaluate_object_typed(handle, pkg_ctx->name, 42 NULL, &buffer, 43 ACPI_TYPE_PACKAGE); 44 if (ACPI_FAILURE(status)) 45 return AE_OK; 46 47 myobj = buffer.pointer; 48 if (!myobj || myobj->package.count != pkg_ctx->length) { 49 kfree(buffer.pointer); 50 return AE_OK; 51 } 52 53 status = acpi_extract_package(myobj, 54 pkg_ctx->format, pkg_ctx->state); 55 if (ACPI_FAILURE(status)) { 56 kfree(buffer.pointer); 57 return AE_OK; 58 } 59 60 kfree(buffer.pointer); 61 pkg_ctx->data_valid = true; 62 return AE_CTRL_TERMINATE; 63 } 64 65 return AE_OK; 66 } 67 68 bool snd_soc_acpi_find_package_from_hid(const u8 hid[ACPI_ID_LEN], 69 struct snd_soc_acpi_package_context *ctx) 70 { 71 acpi_status status; 72 73 status = acpi_get_devices(hid, snd_soc_acpi_find_package, ctx, NULL); 74 75 if (ACPI_FAILURE(status) || !ctx->data_valid) 76 return false; 77 78 return true; 79 } 80 EXPORT_SYMBOL_GPL(snd_soc_acpi_find_package_from_hid); 81 82 struct snd_soc_acpi_mach *snd_soc_acpi_codec_list(void *arg) 83 { 84 struct snd_soc_acpi_mach *mach = arg; 85 struct snd_soc_acpi_codecs *codec_list = 86 (struct snd_soc_acpi_codecs *) mach->quirk_data; 87 int i; 88 89 if (mach->quirk_data == NULL) 90 return mach; 91 92 for (i = 0; i < codec_list->num_codecs; i++) { 93 if (!acpi_dev_present(codec_list->codecs[i], NULL, -1)) 94 return NULL; 95 } 96 97 return mach; 98 } 99 EXPORT_SYMBOL_GPL(snd_soc_acpi_codec_list); 100 101 MODULE_LICENSE("GPL v2"); 102 MODULE_DESCRIPTION("ALSA SoC ACPI module"); 103