summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorEmil Lundmark <lndmrk@chromium.org>2018-05-22 18:22:41 +0200
committerchrome-bot <chrome-bot@chromium.org>2018-05-29 17:15:25 -0700
commitaca6cb220c1aab9debf0fd604a6f3502d29122ec (patch)
treea7aeffebf2bd9d45f26c632587bdd9b7c8f7189b /common
parent65cd9c106c8ac1e3425acec534e71744c3b472e5 (diff)
downloadchrome-ec-aca6cb220c1aab9debf0fd604a6f3502d29122ec.tar.gz
acpi: Add map for controlling USB port power
Some devices have GPIO pins that control USB port power connected to the EC, so they cannot be toggled by ACPI. This patch adds a memory map between the EC and ACPI that can be used on such devices. It can hold the power state of up to 8 USB ports. Currently, only dumb power ports are supported. BUG=chromium:833436 BRANCH=fizz TEST=On a fizz that runs BIOS with EC_ACPI_MEM_USB_PORT_POWER mapped, check that both reads and writes are propagated. Change-Id: I413defcb9e4d234fea7f54d46b6b8a1a10efa31e Signed-off-by: Emil Lundmark <lndmrk@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1069273 Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com> Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
Diffstat (limited to 'common')
-rw-r--r--common/acpi.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/common/acpi.c b/common/acpi.c
index 7ef3d81412..b17393cbcf 100644
--- a/common/acpi.c
+++ b/common/acpi.c
@@ -8,6 +8,7 @@
#include "common.h"
#include "console.h"
#include "dptf.h"
+#include "gpio.h"
#include "hooks.h"
#include "host_command.h"
#include "keyboard_backlight.h"
@@ -16,6 +17,7 @@
#include "tablet_mode.h"
#include "pwm.h"
#include "timer.h"
+#include "usb_charge.h"
#include "util.h"
/* Console output macros */
@@ -37,6 +39,10 @@ static int __bss_slow dptf_temp_sensor_id; /* last sensor ID written */
static int __bss_slow dptf_temp_threshold; /* last threshold written */
#endif
+#ifdef CONFIG_USB_PORT_POWER_DUMB
+extern const int usb_port_enable[USB_PORT_COUNT];
+#endif
+
/*
* Keep a read cache of four bytes when burst mode is enabled, which is the
* size of the largest non-string memmap data type.
@@ -203,6 +209,26 @@ int acpi_ap_to_ec(int is_cmd, uint8_t value, uint8_t *resultptr)
result = val >> (8 * off);
break;
}
+
+#ifdef CONFIG_USB_PORT_POWER_DUMB
+ case EC_ACPI_MEM_USB_PORT_POWER: {
+ int i;
+ const int port_count = MIN(8, USB_PORT_COUNT);
+
+ /*
+ * Convert each USB port power GPIO signal to a bit
+ * field with max size 8 bits. USB port ID (index) 0 is
+ * the least significant bit.
+ */
+ result = 0;
+ for (i = 0; i < port_count; ++i) {
+ if (gpio_get_level(usb_port_enable[i]) != 0)
+ result |= 1 << i;
+ }
+ break;
+ }
+#endif
+
default:
result = acpi_read(acpi_addr);
break;
@@ -267,6 +293,35 @@ int acpi_ap_to_ec(int is_cmd, uint8_t value, uint8_t *resultptr)
}
break;
#endif
+
+#ifdef CONFIG_USB_PORT_POWER_DUMB
+ case EC_ACPI_MEM_USB_PORT_POWER: {
+ int i;
+ int mode_field = data;
+ const int port_count = MIN(8, USB_PORT_COUNT);
+
+ /*
+ * Read the port power bit field (with max size 8 bits)
+ * and set the charge mode of each USB port accordingly.
+ * USB port ID 0 is the least significant bit.
+ */
+ for (i = 0; i < port_count; ++i) {
+ int mode = USB_CHARGE_MODE_DISABLED;
+
+ if (mode_field & 1)
+ mode = USB_CHARGE_MODE_ENABLED;
+
+ if (usb_charge_set_mode(i, mode)) {
+ CPRINTS("ERROR: could not set charge "
+ "mode of USB port p%d to %d",
+ i, mode);
+ }
+ mode_field >>= 1;
+ }
+ break;
+ }
+#endif
+
default:
CPRINTS("ACPI write 0x%02x = 0x%02x (ignored)",
acpi_addr, data);