2 * soc-apci.c - support for ACPI enumeration.
4 * Copyright (c) 2013-15, Intel Corporation.
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms and conditions of the GNU General Public License,
9 * version 2, as published by the Free Software Foundation.
11 * This program is distributed in the hope it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 #include <sound/soc-acpi.h>
19 static acpi_status
snd_soc_acpi_find_name(acpi_handle handle
, u32 level
,
20 void *context
, void **ret
)
22 struct acpi_device
*adev
;
23 const char *name
= NULL
;
25 if (acpi_bus_get_device(handle
, &adev
))
28 if (adev
->status
.present
&& adev
->status
.functional
) {
29 name
= acpi_dev_name(adev
);
30 *(const char **)ret
= name
;
31 return AE_CTRL_TERMINATE
;
37 const char *snd_soc_acpi_find_name_from_hid(const u8 hid
[ACPI_ID_LEN
])
39 const char *name
= NULL
;
42 status
= acpi_get_devices(hid
, snd_soc_acpi_find_name
, NULL
,
45 if (ACPI_FAILURE(status
) || name
[0] == '\0')
50 EXPORT_SYMBOL_GPL(snd_soc_acpi_find_name_from_hid
);
52 static acpi_status
snd_soc_acpi_mach_match(acpi_handle handle
, u32 level
,
53 void *context
, void **ret
)
55 unsigned long long sta
;
58 *(bool *)context
= true;
59 status
= acpi_evaluate_integer(handle
, "_STA", NULL
, &sta
);
60 if (ACPI_FAILURE(status
) || !(sta
& ACPI_STA_DEVICE_PRESENT
))
61 *(bool *)context
= false;
66 bool snd_soc_acpi_check_hid(const u8 hid
[ACPI_ID_LEN
])
71 status
= acpi_get_devices(hid
, snd_soc_acpi_mach_match
, &found
, NULL
);
73 if (ACPI_FAILURE(status
))
78 EXPORT_SYMBOL_GPL(snd_soc_acpi_check_hid
);
80 struct snd_soc_acpi_mach
*
81 snd_soc_acpi_find_machine(struct snd_soc_acpi_mach
*machines
)
83 struct snd_soc_acpi_mach
*mach
;
85 for (mach
= machines
; mach
->id
[0]; mach
++) {
86 if (snd_soc_acpi_check_hid(mach
->id
) == true) {
87 if (mach
->machine_quirk
)
88 mach
= mach
->machine_quirk(mach
);
94 EXPORT_SYMBOL_GPL(snd_soc_acpi_find_machine
);
96 static acpi_status
snd_soc_acpi_find_package(acpi_handle handle
, u32 level
,
97 void *context
, void **ret
)
99 struct acpi_device
*adev
;
100 acpi_status status
= AE_OK
;
101 struct snd_soc_acpi_package_context
*pkg_ctx
= context
;
103 pkg_ctx
->data_valid
= false;
105 if (acpi_bus_get_device(handle
, &adev
))
108 if (adev
->status
.present
&& adev
->status
.functional
) {
109 struct acpi_buffer buffer
= {ACPI_ALLOCATE_BUFFER
, NULL
};
110 union acpi_object
*myobj
= NULL
;
112 status
= acpi_evaluate_object_typed(handle
, pkg_ctx
->name
,
115 if (ACPI_FAILURE(status
))
118 myobj
= buffer
.pointer
;
119 if (!myobj
|| myobj
->package
.count
!= pkg_ctx
->length
) {
120 kfree(buffer
.pointer
);
124 status
= acpi_extract_package(myobj
,
125 pkg_ctx
->format
, pkg_ctx
->state
);
126 if (ACPI_FAILURE(status
)) {
127 kfree(buffer
.pointer
);
131 kfree(buffer
.pointer
);
132 pkg_ctx
->data_valid
= true;
133 return AE_CTRL_TERMINATE
;
139 bool snd_soc_acpi_find_package_from_hid(const u8 hid
[ACPI_ID_LEN
],
140 struct snd_soc_acpi_package_context
*ctx
)
144 status
= acpi_get_devices(hid
, snd_soc_acpi_find_package
, ctx
, NULL
);
146 if (ACPI_FAILURE(status
) || !ctx
->data_valid
)
151 EXPORT_SYMBOL_GPL(snd_soc_acpi_find_package_from_hid
);
153 struct snd_soc_acpi_mach
*snd_soc_acpi_codec_list(void *arg
)
155 struct snd_soc_acpi_mach
*mach
= arg
;
156 struct snd_soc_acpi_codecs
*codec_list
=
157 (struct snd_soc_acpi_codecs
*) mach
->quirk_data
;
160 if (mach
->quirk_data
== NULL
)
163 for (i
= 0; i
< codec_list
->num_codecs
; i
++) {
164 if (snd_soc_acpi_check_hid(codec_list
->codecs
[i
]) != true)
170 EXPORT_SYMBOL_GPL(snd_soc_acpi_codec_list
);
172 MODULE_LICENSE("GPL v2");
173 MODULE_DESCRIPTION("ALSA SoC ACPI module");