soc-acpi.c 2.5 KB

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