1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright 2019 Google LLC
12 #include <acpi/acpigen.h>
13 #include <asm-generic/gpio.h>
14 #include <asm/acpi_nhlt.h>
15 #include <asm/intel_gnvs.h>
16 #include <asm/intel_pinctrl.h>
18 #include "variant_gpio.h"
20 struct cros_gpio_info {
21 const char *linux_name;
22 enum cros_gpio_t type;
27 int arch_misc_init(void)
32 /* This function is needed if CONFIG_CMDLINE is not enabled */
33 int board_run_command(const char *cmdline)
35 printf("No command line\n");
40 int chromeos_get_gpio(const struct udevice *dev, const char *prop,
41 enum cros_gpio_t type, struct cros_gpio_info *info)
43 struct udevice *pinctrl;
44 struct gpio_desc desc;
47 ret = gpio_request_by_name((struct udevice *)dev, prop, 0, &desc, 0);
49 info->gpio_num = CROS_GPIO_VIRTUAL;
51 return log_msg_ret("gpio", ret);
53 info->gpio_num = desc.offset;
54 info->linux_name = dev_read_string(desc.dev, "linux-name");
55 if (!info->linux_name)
56 return log_msg_ret("linux-name", -ENOENT);
58 /* Get ACPI pin from GPIO library if available */
59 if (info->gpio_num != CROS_GPIO_VIRTUAL) {
60 pinctrl = dev_get_parent(desc.dev);
61 info->gpio_num = intel_pinctrl_get_acpi_pin(pinctrl,
64 info->flags = desc.flags & GPIOD_ACTIVE_LOW ? CROS_GPIO_ACTIVE_LOW :
65 CROS_GPIO_ACTIVE_HIGH;
67 dm_gpio_free(desc.dev, &desc);
72 static int chromeos_acpi_gpio_generate(const struct udevice *dev,
75 struct cros_gpio_info info[3];
80 ret = chromeos_get_gpio(dev, "recovery-gpios", CROS_GPIO_REC, &info[0]);
82 return log_msg_ret("rec", ret);
83 ret = chromeos_get_gpio(dev, "write-protect-gpios", CROS_GPIO_WP,
86 return log_msg_ret("rec", ret);
87 ret = chromeos_get_gpio(dev, "phase-enforce-gpios", CROS_GPIO_PE,
90 return log_msg_ret("rec", ret);
91 acpigen_write_scope(ctx, "\\");
92 acpigen_write_name(ctx, "OIPG");
93 acpigen_write_package(ctx, count);
94 for (i = 0; i < count; i++) {
95 acpigen_write_package(ctx, 4);
96 acpigen_write_integer(ctx, info[i].type);
97 acpigen_write_integer(ctx, info[i].flags);
98 acpigen_write_integer(ctx, info[i].gpio_num);
99 acpigen_write_string(ctx, info[i].linux_name);
100 acpigen_pop_len(ctx);
103 acpigen_pop_len(ctx);
104 acpigen_pop_len(ctx);
109 static int coral_write_acpi_tables(const struct udevice *dev,
110 struct acpi_ctx *ctx)
112 struct acpi_global_nvs *gnvs;
114 const char *oem_id = "coral";
115 const char *oem_table_id = "coral";
116 u32 oem_revision = 3;
119 gnvs = bloblist_find(BLOBLISTT_ACPI_GNVS, sizeof(*gnvs));
121 return log_msg_ret("bloblist", -ENOENT);
127 log_debug("Setting up NHLT\n");
128 ret = acpi_setup_nhlt(ctx, nhlt);
130 return log_msg_ret("setup", ret);
132 /* Update NHLT GNVS Data */
133 gnvs->nhla = (uintptr_t)ctx->current;
134 gnvs->nhll = nhlt_current_size(nhlt);
136 ret = nhlt_serialise_oem_overrides(ctx, nhlt, oem_id, oem_table_id,
139 return log_msg_ret("serialise", ret);
144 struct acpi_ops coral_acpi_ops = {
145 .write_tables = coral_write_acpi_tables,
146 .inject_dsdt = chromeos_acpi_gpio_generate,
149 struct sysinfo_ops coral_sysinfo_ops = {
152 #if !CONFIG_IS_ENABLED(OF_PLATDATA)
153 static const struct udevice_id coral_ids[] = {
154 { .compatible = "google,coral" },
159 U_BOOT_DRIVER(coral_drv) = {
161 .id = UCLASS_SYSINFO,
162 .of_match = of_match_ptr(coral_ids),
163 .ops = &coral_sysinfo_ops,
164 ACPI_OPS_PTR(&coral_acpi_ops)