]>
Commit | Line | Data |
---|---|---|
7730bb13 KM |
1 | // SPDX-License-Identifier: GPL-2.0 |
2 | // | |
3 | // soc-apci.c - support for ACPI enumeration. | |
4 | // | |
5 | // Copyright (c) 2013-15, Intel Corporation. | |
95f09801 | 6 | |
7feb2f78 | 7 | #include <sound/soc-acpi.h> |
95f09801 | 8 | |
7feb2f78 PLB |
9 | struct snd_soc_acpi_mach * |
10 | snd_soc_acpi_find_machine(struct snd_soc_acpi_mach *machines) | |
95f09801 | 11 | { |
7feb2f78 | 12 | struct snd_soc_acpi_mach *mach; |
a3e620f8 | 13 | struct snd_soc_acpi_mach *mach_alt; |
95f09801 | 14 | |
7827d669 | 15 | for (mach = machines; mach->id[0]; mach++) { |
0d5ea120 | 16 | if (acpi_dev_present(mach->id, NULL, -1)) { |
a3e620f8 KJ |
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 | ||
5c256045 | 24 | return mach; |
7827d669 N |
25 | } |
26 | } | |
95f09801 VK |
27 | return NULL; |
28 | } | |
7feb2f78 | 29 | EXPORT_SYMBOL_GPL(snd_soc_acpi_find_machine); |
8ceffd22 | 30 | |
7feb2f78 PLB |
31 | static acpi_status snd_soc_acpi_find_package(acpi_handle handle, u32 level, |
32 | void *context, void **ret) | |
34218947 PLB |
33 | { |
34 | struct acpi_device *adev; | |
35 | acpi_status status = AE_OK; | |
7feb2f78 | 36 | struct snd_soc_acpi_package_context *pkg_ctx = context; |
34218947 PLB |
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 | ||
7feb2f78 PLB |
74 | bool snd_soc_acpi_find_package_from_hid(const u8 hid[ACPI_ID_LEN], |
75 | struct snd_soc_acpi_package_context *ctx) | |
34218947 PLB |
76 | { |
77 | acpi_status status; | |
78 | ||
7feb2f78 | 79 | status = acpi_get_devices(hid, snd_soc_acpi_find_package, ctx, NULL); |
34218947 PLB |
80 | |
81 | if (ACPI_FAILURE(status) || !ctx->data_valid) | |
82 | return false; | |
83 | ||
84 | return true; | |
85 | } | |
7feb2f78 | 86 | EXPORT_SYMBOL_GPL(snd_soc_acpi_find_package_from_hid); |
34218947 | 87 | |
7feb2f78 | 88 | struct snd_soc_acpi_mach *snd_soc_acpi_codec_list(void *arg) |
54746dab | 89 | { |
7feb2f78 PLB |
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; | |
54746dab N |
93 | int i; |
94 | ||
95 | if (mach->quirk_data == NULL) | |
96 | return mach; | |
97 | ||
98 | for (i = 0; i < codec_list->num_codecs; i++) { | |
0d5ea120 | 99 | if (!acpi_dev_present(codec_list->codecs[i], NULL, -1)) |
54746dab N |
100 | return NULL; |
101 | } | |
102 | ||
103 | return mach; | |
104 | } | |
7feb2f78 | 105 | EXPORT_SYMBOL_GPL(snd_soc_acpi_codec_list); |
54746dab | 106 | |
8ceffd22 | 107 | MODULE_LICENSE("GPL v2"); |
7feb2f78 | 108 | MODULE_DESCRIPTION("ALSA SoC ACPI module"); |