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