acpi_i2c.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright 2019 Google LLC
  4. */
  5. #include <common.h>
  6. #include <dm.h>
  7. #include <i2c.h>
  8. #include <log.h>
  9. #include <acpi/acpi_device.h>
  10. #include <acpi/acpigen.h>
  11. #include <acpi/acpi_dp.h>
  12. #ifdef CONFIG_X86
  13. #include <asm/intel_pinctrl_defs.h>
  14. #endif
  15. #include <asm-generic/gpio.h>
  16. #include <dm/acpi.h>
  17. static bool acpi_i2c_add_gpios_to_crs(struct acpi_i2c_priv *priv)
  18. {
  19. /*
  20. * Return false if:
  21. * 1. Request to explicitly disable export of GPIOs in CRS, or
  22. * 2. Both reset and enable GPIOs are not provided.
  23. */
  24. if (priv->disable_gpio_export_in_crs ||
  25. (!dm_gpio_is_valid(&priv->reset_gpio) &&
  26. !dm_gpio_is_valid(&priv->enable_gpio)))
  27. return false;
  28. return true;
  29. }
  30. static int acpi_i2c_write_gpio(struct acpi_ctx *ctx, struct gpio_desc *gpio,
  31. int *curindex)
  32. {
  33. int ret;
  34. if (!dm_gpio_is_valid(gpio))
  35. return -ENOENT;
  36. acpi_device_write_gpio_desc(ctx, gpio);
  37. ret = *curindex;
  38. (*curindex)++;
  39. return ret;
  40. }
  41. int acpi_i2c_fill_ssdt(const struct udevice *dev, struct acpi_ctx *ctx)
  42. {
  43. int reset_gpio_index = -1, enable_gpio_index = -1, irq_gpio_index = -1;
  44. enum i2c_device_t type = dev_get_driver_data(dev);
  45. struct acpi_i2c_priv *priv = dev_get_priv(dev);
  46. struct acpi_dp *dsd = NULL;
  47. char scope[ACPI_PATH_MAX];
  48. char name[ACPI_NAME_MAX];
  49. int tx_state_val;
  50. int curindex = 0;
  51. int ret;
  52. #ifdef CONFIG_X86
  53. tx_state_val = PAD_CFG0_TX_STATE;
  54. #elif defined(CONFIG_SANDBOX)
  55. tx_state_val = BIT(7); /* test value */
  56. #else
  57. #error "Not supported on this architecture"
  58. #endif
  59. ret = acpi_get_name(dev, name);
  60. if (ret)
  61. return log_msg_ret("name", ret);
  62. ret = acpi_device_scope(dev, scope, sizeof(scope));
  63. if (ret)
  64. return log_msg_ret("scope", ret);
  65. /* Device */
  66. acpigen_write_scope(ctx, scope);
  67. acpigen_write_device(ctx, name);
  68. acpigen_write_name_string(ctx, "_HID", priv->hid);
  69. if (type == I2C_DEVICE_HID_OVER_I2C)
  70. acpigen_write_name_string(ctx, "_CID", "PNP0C50");
  71. acpigen_write_name_integer(ctx, "_UID", priv->uid);
  72. acpigen_write_name_string(ctx, "_DDN", priv->desc);
  73. acpigen_write_sta(ctx, acpi_device_status(dev));
  74. /* Resources */
  75. acpigen_write_name(ctx, "_CRS");
  76. acpigen_write_resourcetemplate_header(ctx);
  77. acpi_device_write_i2c_dev(ctx, dev);
  78. /* Use either Interrupt() or GpioInt() */
  79. if (dm_gpio_is_valid(&priv->irq_gpio)) {
  80. irq_gpio_index = acpi_i2c_write_gpio(ctx, &priv->irq_gpio,
  81. &curindex);
  82. } else {
  83. ret = acpi_device_write_interrupt_irq(ctx, &priv->irq);
  84. if (ret < 0)
  85. return log_msg_ret("irq", ret);
  86. }
  87. if (acpi_i2c_add_gpios_to_crs(priv)) {
  88. reset_gpio_index = acpi_i2c_write_gpio(ctx, &priv->reset_gpio,
  89. &curindex);
  90. enable_gpio_index = acpi_i2c_write_gpio(ctx, &priv->enable_gpio,
  91. &curindex);
  92. }
  93. acpigen_write_resourcetemplate_footer(ctx);
  94. /* Wake capabilities */
  95. if (priv->wake) {
  96. acpigen_write_name_integer(ctx, "_S0W", 4);
  97. acpigen_write_prw(ctx, priv->wake, 3);
  98. }
  99. /* DSD */
  100. if (priv->probed || priv->property_count || priv->compat_string ||
  101. reset_gpio_index >= 0 || enable_gpio_index >= 0 ||
  102. irq_gpio_index >= 0) {
  103. char path[ACPI_PATH_MAX];
  104. ret = acpi_device_path(dev, path, sizeof(path));
  105. if (ret)
  106. return log_msg_ret("path", ret);
  107. dsd = acpi_dp_new_table("_DSD");
  108. if (priv->compat_string)
  109. acpi_dp_add_string(dsd, "compatible",
  110. priv->compat_string);
  111. if (priv->probed)
  112. acpi_dp_add_integer(dsd, "linux,probed", 1);
  113. if (irq_gpio_index >= 0)
  114. acpi_dp_add_gpio(dsd, "irq-gpios", path,
  115. irq_gpio_index, 0,
  116. priv->irq_gpio.flags &
  117. GPIOD_ACTIVE_LOW ?
  118. ACPI_GPIO_ACTIVE_LOW : 0);
  119. if (reset_gpio_index >= 0)
  120. acpi_dp_add_gpio(dsd, "reset-gpios", path,
  121. reset_gpio_index, 0,
  122. priv->reset_gpio.flags &
  123. GPIOD_ACTIVE_LOW ?
  124. ACPI_GPIO_ACTIVE_LOW : 0);
  125. if (enable_gpio_index >= 0)
  126. acpi_dp_add_gpio(dsd, "enable-gpios", path,
  127. enable_gpio_index, 0,
  128. priv->enable_gpio.flags &
  129. GPIOD_ACTIVE_LOW ?
  130. ACPI_GPIO_ACTIVE_LOW : 0);
  131. /* Generic property list is not supported */
  132. acpi_dp_write(ctx, dsd);
  133. }
  134. /* Power Resource */
  135. if (priv->has_power_resource) {
  136. ret = acpi_device_add_power_res(ctx, tx_state_val,
  137. "\\_SB.GPC0", "\\_SB.SPC0",
  138. &priv->reset_gpio, priv->reset_delay_ms,
  139. priv->reset_off_delay_ms, &priv->enable_gpio,
  140. priv->enable_delay_ms, priv->enable_off_delay_ms,
  141. &priv->stop_gpio, priv->stop_delay_ms,
  142. priv->stop_off_delay_ms);
  143. if (ret)
  144. return log_msg_ret("power", ret);
  145. }
  146. if (priv->hid_desc_reg_offset) {
  147. ret = acpi_device_write_dsm_i2c_hid(ctx,
  148. priv->hid_desc_reg_offset);
  149. if (ret)
  150. return log_msg_ret("dsm", ret);
  151. }
  152. acpigen_pop_len(ctx); /* Device */
  153. acpigen_pop_len(ctx); /* Scope */
  154. return 0;
  155. }
  156. int acpi_i2c_ofdata_to_platdata(struct udevice *dev)
  157. {
  158. struct acpi_i2c_priv *priv = dev_get_priv(dev);
  159. gpio_request_by_name(dev, "reset-gpios", 0, &priv->reset_gpio,
  160. GPIOD_IS_OUT);
  161. gpio_request_by_name(dev, "enable-gpios", 0, &priv->enable_gpio,
  162. GPIOD_IS_OUT);
  163. gpio_request_by_name(dev, "irq-gpios", 0, &priv->irq_gpio, GPIOD_IS_IN);
  164. gpio_request_by_name(dev, "stop-gpios", 0, &priv->stop_gpio,
  165. GPIOD_IS_OUT);
  166. irq_get_by_index(dev, 0, &priv->irq);
  167. priv->hid = dev_read_string(dev, "acpi,hid");
  168. if (!priv->hid)
  169. return log_msg_ret("hid", -EINVAL);
  170. dev_read_u32(dev, "acpi,uid", &priv->uid);
  171. priv->desc = dev_read_string(dev, "acpi,ddn");
  172. dev_read_u32(dev, "acpi,wake", &priv->wake);
  173. priv->probed = dev_read_bool(dev, "linux,probed");
  174. priv->compat_string = dev_read_string(dev, "acpi,compatible");
  175. priv->has_power_resource = dev_read_bool(dev,
  176. "acpi,has-power-resource");
  177. dev_read_u32(dev, "hid-descr-addr", &priv->hid_desc_reg_offset);
  178. dev_read_u32(dev, "reset-delay-ms", &priv->reset_delay_ms);
  179. dev_read_u32(dev, "reset-off-delay-ms", &priv->reset_off_delay_ms);
  180. dev_read_u32(dev, "enable-delay-ms", &priv->enable_delay_ms);
  181. dev_read_u32(dev, "enable-off-delay-ms", &priv->enable_off_delay_ms);
  182. dev_read_u32(dev, "stop-delay-ms", &priv->stop_delay_ms);
  183. dev_read_u32(dev, "stop-off-delay-ms", &priv->stop_off_delay_ms);
  184. return 0;
  185. }
  186. /* Use name specified in priv or build one from I2C address */
  187. static int acpi_i2c_get_name(const struct udevice *dev, char *out_name)
  188. {
  189. struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
  190. struct acpi_i2c_priv *priv = dev_get_priv(dev);
  191. snprintf(out_name, ACPI_NAME_MAX,
  192. priv->hid_desc_reg_offset ? "H%03X" : "D%03X",
  193. chip->chip_addr);
  194. return 0;
  195. }
  196. struct acpi_ops acpi_i2c_ops = {
  197. .fill_ssdt = acpi_i2c_fill_ssdt,
  198. .get_name = acpi_i2c_get_name,
  199. };