max98357a.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * max98357a.c -- MAX98357A Audio driver
  4. *
  5. * Copyright 2019 Google LLC
  6. * Parts taken from coreboot
  7. */
  8. #include <common.h>
  9. #include <audio_codec.h>
  10. #include <dm.h>
  11. #include <log.h>
  12. #include <sound.h>
  13. #include <acpi/acpigen.h>
  14. #include <acpi/acpi_device.h>
  15. #include <acpi/acpi_dp.h>
  16. #include <asm-generic/gpio.h>
  17. #ifdef CONFIG_X86
  18. #include <asm/acpi_nhlt.h>
  19. #endif
  20. #include <dt-bindings/sound/nhlt.h>
  21. #include <dm/acpi.h>
  22. struct max98357a_priv {
  23. struct gpio_desc sdmode_gpio;
  24. };
  25. static int max98357a_of_to_plat(struct udevice *dev)
  26. {
  27. struct max98357a_priv *priv = dev_get_priv(dev);
  28. int ret;
  29. ret = gpio_request_by_name(dev, "sdmode-gpios", 0, &priv->sdmode_gpio,
  30. GPIOD_IS_IN);
  31. if (ret)
  32. return log_msg_ret("gpio", ret);
  33. return 0;
  34. }
  35. static int max98357a_acpi_fill_ssdt(const struct udevice *dev,
  36. struct acpi_ctx *ctx)
  37. {
  38. struct max98357a_priv *priv = dev_get_priv(dev);
  39. char scope[ACPI_PATH_MAX];
  40. char name[ACPI_NAME_MAX];
  41. char path[ACPI_PATH_MAX];
  42. struct acpi_dp *dp;
  43. int ret;
  44. ret = acpi_device_scope(dev, scope, sizeof(scope));
  45. if (ret)
  46. return log_msg_ret("scope", ret);
  47. ret = acpi_get_name(dev, name);
  48. if (ret)
  49. return log_msg_ret("name", ret);
  50. /* Device */
  51. acpigen_write_scope(ctx, scope);
  52. acpigen_write_device(ctx, name);
  53. acpigen_write_name_string(ctx, "_HID",
  54. dev_read_string(dev, "acpi,hid"));
  55. acpigen_write_name_integer(ctx, "_UID", 0);
  56. acpigen_write_name_string(ctx, "_DDN",
  57. dev_read_string(dev, "acpi,ddn"));
  58. acpigen_write_sta(ctx, acpi_device_status(dev));
  59. /* Resources */
  60. acpigen_write_name(ctx, "_CRS");
  61. acpigen_write_resourcetemplate_header(ctx);
  62. ret = acpi_device_write_gpio_desc(ctx, &priv->sdmode_gpio);
  63. if (ret < 0)
  64. return log_msg_ret("gpio", ret);
  65. acpigen_write_resourcetemplate_footer(ctx);
  66. /* _DSD for devicetree properties */
  67. /* This points to the first pin in the first gpio entry in _CRS */
  68. ret = acpi_device_path(dev, path, sizeof(path));
  69. if (ret)
  70. return log_msg_ret("path", ret);
  71. dp = acpi_dp_new_table("_DSD");
  72. acpi_dp_add_gpio(dp, "sdmode-gpio", path, 0, 0,
  73. priv->sdmode_gpio.flags & GPIOD_ACTIVE_LOW ?
  74. ACPI_GPIO_ACTIVE_LOW : ACPI_GPIO_ACTIVE_HIGH);
  75. acpi_dp_add_integer(dp, "sdmode-delay",
  76. dev_read_u32_default(dev, "sdmode-delay", 0));
  77. acpi_dp_write(ctx, dp);
  78. acpigen_pop_len(ctx); /* Device */
  79. acpigen_pop_len(ctx); /* Scope */
  80. return 0;
  81. }
  82. /* For now only X86 boards support NHLT */
  83. #ifdef CONFIG_X86
  84. static const struct nhlt_format_config max98357a_formats[] = {
  85. /* 48 KHz 24-bits per sample. */
  86. {
  87. .num_channels = 2,
  88. .sample_freq_khz = 48,
  89. .container_bits_per_sample = 32,
  90. .valid_bits_per_sample = 24,
  91. .settings_file = "max98357-render-2ch-48khz-24b.dat",
  92. },
  93. };
  94. static const struct nhlt_endp_descriptor max98357a_descriptors[] = {
  95. {
  96. .link = NHLT_LINK_SSP,
  97. .device = NHLT_SSP_DEV_I2S,
  98. .direction = NHLT_DIR_RENDER,
  99. .vid = NHLT_VID,
  100. .did = NHLT_DID_SSP,
  101. .formats = max98357a_formats,
  102. .num_formats = ARRAY_SIZE(max98357a_formats),
  103. },
  104. };
  105. static int max98357a_acpi_setup_nhlt(const struct udevice *dev,
  106. struct acpi_ctx *ctx)
  107. {
  108. u32 hwlink;
  109. int ret;
  110. if (dev_read_u32(dev, "acpi,audio-link", &hwlink))
  111. return log_msg_ret("link", -EINVAL);
  112. /* Virtual bus id of SSP links are the hardware port ids proper. */
  113. ret = nhlt_add_ssp_endpoints(ctx->nhlt, hwlink, max98357a_descriptors,
  114. ARRAY_SIZE(max98357a_descriptors));
  115. if (ret)
  116. return log_msg_ret("add", ret);
  117. return 0;
  118. }
  119. #endif
  120. struct acpi_ops max98357a_acpi_ops = {
  121. .fill_ssdt = max98357a_acpi_fill_ssdt,
  122. #ifdef CONFIG_X86
  123. .setup_nhlt = max98357a_acpi_setup_nhlt,
  124. #endif
  125. };
  126. static const struct audio_codec_ops max98357a_ops = {
  127. };
  128. static const struct udevice_id max98357a_ids[] = {
  129. { .compatible = "maxim,max98357a" },
  130. { }
  131. };
  132. U_BOOT_DRIVER(max98357a) = {
  133. .name = "max98357a",
  134. .id = UCLASS_AUDIO_CODEC,
  135. .of_match = max98357a_ids,
  136. .of_to_plat = max98357a_of_to_plat,
  137. .ops = &max98357a_ops,
  138. ACPI_OPS_PTR(&max98357a_acpi_ops)
  139. };