2018-07-02 09:24:04 +03:00
// SPDX-License-Identifier: GPL-2.0
//
// soc-apci.c - support for ACPI enumeration.
//
// Copyright (c) 2013-15, Intel Corporation.
2015-11-05 19:04:11 +03:00
2019-04-13 18:15:18 +03:00
# include <linux/export.h>
# include <linux/module.h>
2017-10-13 02:49:38 +03:00
# include <sound/soc-acpi.h>
2015-11-05 19:04:11 +03:00
2021-10-29 20:14:04 +03:00
static bool snd_soc_acpi_id_present ( struct snd_soc_acpi_mach * machine )
{
const struct snd_soc_acpi_codecs * comp_ids = machine - > comp_ids ;
int i ;
if ( machine - > id [ 0 ] ) {
if ( acpi_dev_present ( machine - > id , NULL , - 1 ) )
return true ;
}
if ( comp_ids ) {
for ( i = 0 ; i < comp_ids - > num_codecs ; i + + ) {
2021-11-18 18:30:14 +03:00
if ( acpi_dev_present ( comp_ids - > codecs [ i ] , NULL , - 1 ) ) {
strscpy ( machine - > id , comp_ids - > codecs [ i ] , ACPI_ID_LEN ) ;
2021-10-29 20:14:04 +03:00
return true ;
2021-11-18 18:30:14 +03:00
}
2021-10-29 20:14:04 +03:00
}
}
return false ;
}
2017-10-13 02:49:38 +03:00
struct snd_soc_acpi_mach *
snd_soc_acpi_find_machine ( struct snd_soc_acpi_mach * machines )
2015-11-05 19:04:11 +03:00
{
2017-10-13 02:49:38 +03:00
struct snd_soc_acpi_mach * mach ;
2018-11-17 03:47:04 +03:00
struct snd_soc_acpi_mach * mach_alt ;
2015-11-05 19:04:11 +03:00
2021-10-29 20:14:04 +03:00
for ( mach = machines ; mach - > id [ 0 ] | | mach - > comp_ids ; mach + + ) {
if ( snd_soc_acpi_id_present ( mach ) ) {
2018-11-17 03:47:04 +03:00
if ( mach - > machine_quirk ) {
mach_alt = mach - > machine_quirk ( mach ) ;
if ( ! mach_alt )
continue ; /* not full match, ignore */
mach = mach_alt ;
}
2018-01-05 23:55:33 +03:00
return mach ;
2017-05-15 11:12:14 +03:00
}
}
2015-11-05 19:04:11 +03:00
return NULL ;
}
2017-10-13 02:49:38 +03:00
EXPORT_SYMBOL_GPL ( snd_soc_acpi_find_machine ) ;
2016-02-08 08:15:39 +03:00
2017-10-13 02:49:38 +03:00
static acpi_status snd_soc_acpi_find_package ( acpi_handle handle , u32 level ,
void * context , void * * ret )
2016-11-13 03:07:44 +03:00
{
2022-01-26 22:48:49 +03:00
struct acpi_device * adev = acpi_fetch_acpi_dev ( handle ) ;
2021-04-16 22:11:40 +03:00
acpi_status status ;
2017-10-13 02:49:38 +03:00
struct snd_soc_acpi_package_context * pkg_ctx = context ;
2016-11-13 03:07:44 +03:00
pkg_ctx - > data_valid = false ;
2022-01-26 22:48:49 +03:00
if ( adev & & adev - > status . present & & adev - > status . functional ) {
2016-11-13 03:07:44 +03:00
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER , NULL } ;
union acpi_object * myobj = NULL ;
status = acpi_evaluate_object_typed ( handle , pkg_ctx - > name ,
NULL , & buffer ,
ACPI_TYPE_PACKAGE ) ;
if ( ACPI_FAILURE ( status ) )
return AE_OK ;
myobj = buffer . pointer ;
if ( ! myobj | | myobj - > package . count ! = pkg_ctx - > length ) {
kfree ( buffer . pointer ) ;
return AE_OK ;
}
status = acpi_extract_package ( myobj ,
pkg_ctx - > format , pkg_ctx - > state ) ;
if ( ACPI_FAILURE ( status ) ) {
kfree ( buffer . pointer ) ;
return AE_OK ;
}
kfree ( buffer . pointer ) ;
pkg_ctx - > data_valid = true ;
return AE_CTRL_TERMINATE ;
}
return AE_OK ;
}
2017-10-13 02:49:38 +03:00
bool snd_soc_acpi_find_package_from_hid ( const u8 hid [ ACPI_ID_LEN ] ,
struct snd_soc_acpi_package_context * ctx )
2016-11-13 03:07:44 +03:00
{
acpi_status status ;
2017-10-13 02:49:38 +03:00
status = acpi_get_devices ( hid , snd_soc_acpi_find_package , ctx , NULL ) ;
2016-11-13 03:07:44 +03:00
if ( ACPI_FAILURE ( status ) | | ! ctx - > data_valid )
return false ;
return true ;
}
2017-10-13 02:49:38 +03:00
EXPORT_SYMBOL_GPL ( snd_soc_acpi_find_package_from_hid ) ;
2016-11-13 03:07:44 +03:00
2017-10-13 02:49:38 +03:00
struct snd_soc_acpi_mach * snd_soc_acpi_codec_list ( void * arg )
2017-05-15 11:12:15 +03:00
{
2017-10-13 02:49:38 +03:00
struct snd_soc_acpi_mach * mach = arg ;
struct snd_soc_acpi_codecs * codec_list =
( struct snd_soc_acpi_codecs * ) mach - > quirk_data ;
2017-05-15 11:12:15 +03:00
int i ;
if ( mach - > quirk_data = = NULL )
return mach ;
for ( i = 0 ; i < codec_list - > num_codecs ; i + + ) {
2018-01-05 23:55:34 +03:00
if ( ! acpi_dev_present ( codec_list - > codecs [ i ] , NULL , - 1 ) )
2017-05-15 11:12:15 +03:00
return NULL ;
}
return mach ;
}
2017-10-13 02:49:38 +03:00
EXPORT_SYMBOL_GPL ( snd_soc_acpi_codec_list ) ;
2017-05-15 11:12:15 +03:00
2016-02-08 08:15:39 +03:00
MODULE_LICENSE ( " GPL v2 " ) ;
2017-10-13 02:49:38 +03:00
MODULE_DESCRIPTION ( " ALSA SoC ACPI module " ) ;