zako: Support checking AC adapter type and alert if adapter is wrong.

To detect and alert user that an incompatible or insufficient AC adapter is
connected, we have to render the firmware bitmap screen and then shutdown.

The detection is done by checking a specific GPIO (48) which is reserved for
reporting AC adapter type.

BUG=chrome-os-partner:25024
TEST=emerge-zako depthcharge chromeos-bootimage
BRANCH=zako

Change-Id: I99e3449ea307bb740e3369ce7f5581799c11eace
Reviewed-on: https://chromium-review.googlesource.com/190684
Tested-by: Hung-Te Lin <hungte@chromium.org>
Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
Commit-Queue: Hung-Te Lin <hungte@chromium.org>
diff --git a/src/board/zako/board.c b/src/board/zako/board.c
index 5ef18e5..3e09213 100644
--- a/src/board/zako/board.c
+++ b/src/board/zako/board.c
@@ -20,6 +20,7 @@
  * MA 02111-1307 USA
  */
 
+#include <libpayload.h>
 #include <pci.h>
 
 #include "base/init_funcs.h"
@@ -35,8 +36,35 @@
 #include "drivers/storage/blockdev.h"
 #include "drivers/tpm/lpc.h"
 #include "drivers/tpm/tpm.h"
+#include "vboot/util/commonparams.h"
 #include "vboot/util/flag.h"
 
+#include <vboot_api.h>
+#include <vboot_nvstorage.h>
+
+VbError_t VbDisplayScreen(VbCommonParams *cparams, uint32_t screen, int force,
+                          VbNvContext *vncptr);
+
+static void check_power_adapter(void)
+{
+	// GPIO48 = ADP_ID:
+	//  0 = 65W or higer, or if the MB does not support probing adapter.
+	//  1 = lower than 65W (ex, 45W, which we should alert and shutdown).
+	LpPchGpio *ad_type = new_lp_pch_gpio_input(48);
+	if (!ad_type->ops.get(&ad_type->ops))
+		return;
+
+	// Minimal setup of vboot environment for displaying GBB screen.
+	common_params_init(0);
+	cparams.gbb = (struct GoogleBinaryBlockHeader *)cparams.gbb_data;
+	VbNvContext vnc;
+	VbExNvStorageRead(vnc.raw);
+	VbNvSetup(&vnc);
+	VbDisplayScreen(&cparams, VB_SCREEN_WRONG_ADAPTER, 0, &vnc);
+	VbExSleepMs(60 * 1000);
+	power_off();
+}
+
 static int board_setup(void)
 {
 	if (sysinfo_install_flags())
@@ -66,6 +94,7 @@
 	if (tpm_set_ops(&tpm->ops))
 		return 1;
 
+	check_power_adapter();
 	return 0;
 }
 
diff --git a/src/vboot/callbacks/display.c b/src/vboot/callbacks/display.c
index f271182..55ce9b1 100644
--- a/src/vboot/callbacks/display.c
+++ b/src/vboot/callbacks/display.c
@@ -101,6 +101,9 @@
 	case VB_SCREEN_WAIT:
 		msg = "wait for ec update";
 		break;
+	case VB_SCREEN_WRONG_ADAPTER:
+		msg = "wrong power adapter";
+		break;
 	default:
 		printf("Not a valid screen type: %d.\n", screen_type);
 		return VBERROR_INVALID_SCREEN_INDEX;