1 // SPDX-License-Identifier: GPL-2.0
3 // soc-apci.c - support for ACPI enumeration.
5 // Copyright (c) 2013-15, Intel Corporation.
7 #include <linux/export.h>
8 #include <linux/module.h>
9 #include <sound/soc-acpi.h>
11 static bool snd_soc_acpi_id_present(struct snd_soc_acpi_mach
*machine
)
13 const struct snd_soc_acpi_codecs
*comp_ids
= machine
->comp_ids
;
17 if (acpi_dev_present(machine
->id
, NULL
, -1))
22 for (i
= 0; i
< comp_ids
->num_codecs
; i
++) {
23 if (acpi_dev_present(comp_ids
->codecs
[i
], NULL
, -1)) {
24 strscpy(machine
->id
, comp_ids
->codecs
[i
], ACPI_ID_LEN
);
33 struct snd_soc_acpi_mach
*
34 snd_soc_acpi_find_machine(struct snd_soc_acpi_mach
*machines
)
36 struct snd_soc_acpi_mach
*mach
;
37 struct snd_soc_acpi_mach
*mach_alt
;
39 for (mach
= machines
; mach
->id
[0] || mach
->comp_ids
; mach
++) {
40 if (snd_soc_acpi_id_present(mach
)) {
41 if (mach
->machine_quirk
) {
42 mach_alt
= mach
->machine_quirk(mach
);
44 continue; /* not full match, ignore */
53 EXPORT_SYMBOL_GPL(snd_soc_acpi_find_machine
);
55 static acpi_status
snd_soc_acpi_find_package(acpi_handle handle
, u32 level
,
56 void *context
, void **ret
)
58 struct acpi_device
*adev
= acpi_fetch_acpi_dev(handle
);
60 struct snd_soc_acpi_package_context
*pkg_ctx
= context
;
62 pkg_ctx
->data_valid
= false;
64 if (adev
&& adev
->status
.present
&& adev
->status
.functional
) {
65 struct acpi_buffer buffer
= {ACPI_ALLOCATE_BUFFER
, NULL
};
66 union acpi_object
*myobj
= NULL
;
68 status
= acpi_evaluate_object_typed(handle
, pkg_ctx
->name
,
71 if (ACPI_FAILURE(status
))
74 myobj
= buffer
.pointer
;
75 if (!myobj
|| myobj
->package
.count
!= pkg_ctx
->length
) {
76 kfree(buffer
.pointer
);
80 status
= acpi_extract_package(myobj
,
81 pkg_ctx
->format
, pkg_ctx
->state
);
82 if (ACPI_FAILURE(status
)) {
83 kfree(buffer
.pointer
);
87 kfree(buffer
.pointer
);
88 pkg_ctx
->data_valid
= true;
89 return AE_CTRL_TERMINATE
;
95 bool snd_soc_acpi_find_package_from_hid(const u8 hid
[ACPI_ID_LEN
],
96 struct snd_soc_acpi_package_context
*ctx
)
100 status
= acpi_get_devices(hid
, snd_soc_acpi_find_package
, ctx
, NULL
);
102 if (ACPI_FAILURE(status
) || !ctx
->data_valid
)
107 EXPORT_SYMBOL_GPL(snd_soc_acpi_find_package_from_hid
);
109 struct snd_soc_acpi_mach
*snd_soc_acpi_codec_list(void *arg
)
111 struct snd_soc_acpi_mach
*mach
= arg
;
112 struct snd_soc_acpi_codecs
*codec_list
=
113 (struct snd_soc_acpi_codecs
*) mach
->quirk_data
;
116 if (mach
->quirk_data
== NULL
)
119 for (i
= 0; i
< codec_list
->num_codecs
; i
++) {
120 if (!acpi_dev_present(codec_list
->codecs
[i
], NULL
, -1))
126 EXPORT_SYMBOL_GPL(snd_soc_acpi_codec_list
);
128 MODULE_LICENSE("GPL v2");
129 MODULE_DESCRIPTION("ALSA SoC ACPI module");