blob: 969021c32a4dba9fc5f3ab58a5c5bb3766d07956 [file] [log] [blame]
Lee Leahy5cb9dda2015-05-01 10:34:54 -07001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2013 Google Inc.
5 * Copyright (C) 2015 Intel Corp.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
Lee Leahy5cb9dda2015-05-01 10:34:54 -070015 */
16
17#include <arch/io.h>
18#include <device/device.h>
19#include <device/pci.h>
20
21#if IS_ENABLED(CONFIG_EC_GOOGLE_CHROMEEC)
22#include "ec.h"
23#include <ec/google/chromeec/ec.h>
24#endif
25#include <rules.h>
26#include <soc/gpio.h>
27#include <string.h>
28#include <vendorcode/google/chromeos/chromeos.h>
29
30/* The WP status pin lives on GPIO_SSUS_6 which is pad 36 in the SUS well. */
31#define WP_STATUS_PAD 36
32
33#if ENV_RAMSTAGE
34#include <boot/coreboot_tables.h>
35
36#define GPIO_COUNT 6
37#define ACTIVE_LOW 0
38#define ACTIVE_HIGH 1
39
40void fill_lb_gpios(struct lb_gpios *gpios)
41{
42 struct lb_gpio *gpio;
43
44 gpios->size = sizeof(*gpios) + (GPIO_COUNT * sizeof(struct lb_gpio));
45 gpios->count = GPIO_COUNT;
46
47 gpio = gpios->gpios;
48 fill_lb_gpio(gpio++, -1, ACTIVE_HIGH, "write protect",
49 get_write_protect_state());
50 fill_lb_gpio(gpio++, -1, ACTIVE_HIGH, "recovery",
51 recovery_mode_enabled());
52 fill_lb_gpio(gpio++, -1, ACTIVE_HIGH, "developer",
53 get_developer_mode_switch());
54 fill_lb_gpio(gpio++, -1, ACTIVE_HIGH, "lid", get_lid_switch());
55 fill_lb_gpio(gpio++, -1, ACTIVE_HIGH, "power", 0);
56 fill_lb_gpio(gpio++, -1, ACTIVE_HIGH, "oprom", gfx_get_init_done());
57}
58#endif /* ENV_RAMSTAGE */
59
60int get_lid_switch(void)
61{
62#if IS_ENABLED(CONFIG_EC_GOOGLE_CHROMEEC)
63 u8 ec_switches;
64
65 mec_io_bytes(0, EC_LPC_ADDR_MEMMAP + EC_MEMMAP_SWITCHES, 1,
66 &ec_switches, NULL);
67
68 return !!(ec_switches & EC_SWITCH_LID_OPEN);
69#else
70 /* Default to force open. */
71 return 1;
72#endif
73}
74
75int get_developer_mode_switch(void)
76{
77 return 0;
78}
79
80int get_recovery_mode_switch(void)
81{
82#if IS_ENABLED(CONFIG_EC_GOOGLE_CHROMEEC)
83 u8 ec_switches;
84 u32 ec_events;
85 mec_io_bytes(0, EC_LPC_ADDR_MEMMAP + EC_MEMMAP_SWITCHES, 1,
86 &ec_switches, NULL);
87
88 /* If a switch is set, we don't need to look at events. */
89 if (ec_switches & (EC_SWITCH_DEDICATED_RECOVERY))
90 return 1;
91
92 /* Else check if the EC has posted the keyboard recovery event. */
93 ec_events = google_chromeec_get_events_b();
94
95 return !!(ec_events &
96 EC_HOST_EVENT_MASK(EC_HOST_EVENT_KEYBOARD_RECOVERY));
97#else
98 return 0;
99#endif
100}
101
102int clear_recovery_mode_switch(void)
103{
104#if IS_ENABLED(CONFIG_EC_GOOGLE_CHROMEEC)
105 const uint32_t kb_rec_mask =
106 EC_HOST_EVENT_MASK(EC_HOST_EVENT_KEYBOARD_RECOVERY);
107 /* Unconditionally clear the EC recovery request. */
108 return google_chromeec_clear_events_b(kb_rec_mask);
109#else
110 return 0;
111#endif
112}
113
114int get_write_protect_state(void)
115{
116 /*
117 * The vboot loader queries this function in romstage. The GPIOs have
118 * not been set up yet as that configuration is done in ramstage. The
119 * hardware defaults to an input but there is a 20K pulldown. Externally
120 * there is a 10K pullup. Disable the internal pull in romstage so that
121 * there isn't any ambiguity in the reading.
122 */
123#if ENV_ROMSTAGE
124 ssus_disable_internal_pull(WP_STATUS_PAD);
125#endif
126
127 /* WP is enabled when the pin is reading high. */
128 return ssus_get_gpio(WP_STATUS_PAD);
129}