blob: 8e4f984dedc6eaf70b3d6e44d55067fe644286dd [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.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc.
19 */
20
21#include <arch/io.h>
22#include <device/device.h>
23#include <device/pci.h>
24
25#if IS_ENABLED(CONFIG_EC_GOOGLE_CHROMEEC)
26#include "ec.h"
27#include <ec/google/chromeec/ec.h>
28#endif
29#include <rules.h>
30#include <soc/gpio.h>
31#include <string.h>
32#include <vendorcode/google/chromeos/chromeos.h>
33
34/* The WP status pin lives on GPIO_SSUS_6 which is pad 36 in the SUS well. */
35#define WP_STATUS_PAD 36
36
37#if ENV_RAMSTAGE
38#include <boot/coreboot_tables.h>
39
40#define GPIO_COUNT 6
41#define ACTIVE_LOW 0
42#define ACTIVE_HIGH 1
43
44void fill_lb_gpios(struct lb_gpios *gpios)
45{
46 struct lb_gpio *gpio;
47
48 gpios->size = sizeof(*gpios) + (GPIO_COUNT * sizeof(struct lb_gpio));
49 gpios->count = GPIO_COUNT;
50
51 gpio = gpios->gpios;
52 fill_lb_gpio(gpio++, -1, ACTIVE_HIGH, "write protect",
53 get_write_protect_state());
54 fill_lb_gpio(gpio++, -1, ACTIVE_HIGH, "recovery",
55 recovery_mode_enabled());
56 fill_lb_gpio(gpio++, -1, ACTIVE_HIGH, "developer",
57 get_developer_mode_switch());
58 fill_lb_gpio(gpio++, -1, ACTIVE_HIGH, "lid", get_lid_switch());
59 fill_lb_gpio(gpio++, -1, ACTIVE_HIGH, "power", 0);
60 fill_lb_gpio(gpio++, -1, ACTIVE_HIGH, "oprom", gfx_get_init_done());
61}
62#endif /* ENV_RAMSTAGE */
63
64int get_lid_switch(void)
65{
66#if IS_ENABLED(CONFIG_EC_GOOGLE_CHROMEEC)
67 u8 ec_switches;
68
69 mec_io_bytes(0, EC_LPC_ADDR_MEMMAP + EC_MEMMAP_SWITCHES, 1,
70 &ec_switches, NULL);
71
72 return !!(ec_switches & EC_SWITCH_LID_OPEN);
73#else
74 /* Default to force open. */
75 return 1;
76#endif
77}
78
79int get_developer_mode_switch(void)
80{
81 return 0;
82}
83
84int get_recovery_mode_switch(void)
85{
86#if IS_ENABLED(CONFIG_EC_GOOGLE_CHROMEEC)
87 u8 ec_switches;
88 u32 ec_events;
89 mec_io_bytes(0, EC_LPC_ADDR_MEMMAP + EC_MEMMAP_SWITCHES, 1,
90 &ec_switches, NULL);
91
92 /* If a switch is set, we don't need to look at events. */
93 if (ec_switches & (EC_SWITCH_DEDICATED_RECOVERY))
94 return 1;
95
96 /* Else check if the EC has posted the keyboard recovery event. */
97 ec_events = google_chromeec_get_events_b();
98
99 return !!(ec_events &
100 EC_HOST_EVENT_MASK(EC_HOST_EVENT_KEYBOARD_RECOVERY));
101#else
102 return 0;
103#endif
104}
105
106int clear_recovery_mode_switch(void)
107{
108#if IS_ENABLED(CONFIG_EC_GOOGLE_CHROMEEC)
109 const uint32_t kb_rec_mask =
110 EC_HOST_EVENT_MASK(EC_HOST_EVENT_KEYBOARD_RECOVERY);
111 /* Unconditionally clear the EC recovery request. */
112 return google_chromeec_clear_events_b(kb_rec_mask);
113#else
114 return 0;
115#endif
116}
117
118int get_write_protect_state(void)
119{
120 /*
121 * The vboot loader queries this function in romstage. The GPIOs have
122 * not been set up yet as that configuration is done in ramstage. The
123 * hardware defaults to an input but there is a 20K pulldown. Externally
124 * there is a 10K pullup. Disable the internal pull in romstage so that
125 * there isn't any ambiguity in the reading.
126 */
127#if ENV_ROMSTAGE
128 ssus_disable_internal_pull(WP_STATUS_PAD);
129#endif
130
131 /* WP is enabled when the pin is reading high. */
132 return ssus_get_gpio(WP_STATUS_PAD);
133}