xref: /OK3568_Linux_fs/u-boot/include/ec_commands.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
2*4882a593Smuzhiyun  * Use of this source code is governed by a BSD-style license that can be
3*4882a593Smuzhiyun  * found in the LICENSE file.
4*4882a593Smuzhiyun  */
5*4882a593Smuzhiyun 
6*4882a593Smuzhiyun /* Host communication command constants for Chrome EC */
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #ifndef __CROS_EC_COMMANDS_H
9*4882a593Smuzhiyun #define __CROS_EC_COMMANDS_H
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun /*
12*4882a593Smuzhiyun  * Protocol overview
13*4882a593Smuzhiyun  *
14*4882a593Smuzhiyun  * request:  CMD [ P0 P1 P2 ... Pn S ]
15*4882a593Smuzhiyun  * response: ERR [ P0 P1 P2 ... Pn S ]
16*4882a593Smuzhiyun  *
17*4882a593Smuzhiyun  * where the bytes are defined as follow :
18*4882a593Smuzhiyun  *      - CMD is the command code. (defined by EC_CMD_ constants)
19*4882a593Smuzhiyun  *      - ERR is the error code. (defined by EC_RES_ constants)
20*4882a593Smuzhiyun  *      - Px is the optional payload.
21*4882a593Smuzhiyun  *        it is not sent if the error code is not success.
22*4882a593Smuzhiyun  *        (defined by ec_params_ and ec_response_ structures)
23*4882a593Smuzhiyun  *      - S is the checksum which is the sum of all payload bytes.
24*4882a593Smuzhiyun  *
25*4882a593Smuzhiyun  * On LPC, CMD and ERR are sent/received at EC_LPC_ADDR_KERNEL|USER_CMD
26*4882a593Smuzhiyun  * and the payloads are sent/received at EC_LPC_ADDR_KERNEL|USER_PARAM.
27*4882a593Smuzhiyun  * On I2C, all bytes are sent serially in the same message.
28*4882a593Smuzhiyun  */
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun /* Current version of this protocol */
31*4882a593Smuzhiyun #define EC_PROTO_VERSION          0x00000002
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun /* Command version mask */
34*4882a593Smuzhiyun #define EC_VER_MASK(version) (1UL << (version))
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun /* I/O addresses for ACPI commands */
37*4882a593Smuzhiyun #define EC_LPC_ADDR_ACPI_DATA  0x62
38*4882a593Smuzhiyun #define EC_LPC_ADDR_ACPI_CMD   0x66
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun /* I/O addresses for host command */
41*4882a593Smuzhiyun #define EC_LPC_ADDR_HOST_DATA  0x200
42*4882a593Smuzhiyun #define EC_LPC_ADDR_HOST_CMD   0x204
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun /* I/O addresses for host command args and params */
45*4882a593Smuzhiyun /* Protocol version 2 */
46*4882a593Smuzhiyun #define EC_LPC_ADDR_HOST_ARGS    0x800  /* And 0x801, 0x802, 0x803 */
47*4882a593Smuzhiyun #define EC_LPC_ADDR_HOST_PARAM   0x804  /* For version 2 params; size is
48*4882a593Smuzhiyun 					 * EC_PROTO2_MAX_PARAM_SIZE */
49*4882a593Smuzhiyun /* Protocol version 3 */
50*4882a593Smuzhiyun #define EC_LPC_ADDR_HOST_PACKET  0x800  /* Offset of version 3 packet */
51*4882a593Smuzhiyun #define EC_LPC_HOST_PACKET_SIZE  0x100  /* Max size of version 3 packet */
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun /* The actual block is 0x800-0x8ff, but some BIOSes think it's 0x880-0x8ff
54*4882a593Smuzhiyun  * and they tell the kernel that so we have to think of it as two parts. */
55*4882a593Smuzhiyun #define EC_HOST_CMD_REGION0    0x800
56*4882a593Smuzhiyun #define EC_HOST_CMD_REGION1    0x880
57*4882a593Smuzhiyun #define EC_HOST_CMD_REGION_SIZE 0x80
58*4882a593Smuzhiyun 
59*4882a593Smuzhiyun /* EC command register bit functions */
60*4882a593Smuzhiyun #define EC_LPC_CMDR_DATA	(1 << 0)  /* Data ready for host to read */
61*4882a593Smuzhiyun #define EC_LPC_CMDR_PENDING	(1 << 1)  /* Write pending to EC */
62*4882a593Smuzhiyun #define EC_LPC_CMDR_BUSY	(1 << 2)  /* EC is busy processing a command */
63*4882a593Smuzhiyun #define EC_LPC_CMDR_CMD		(1 << 3)  /* Last host write was a command */
64*4882a593Smuzhiyun #define EC_LPC_CMDR_ACPI_BRST	(1 << 4)  /* Burst mode (not used) */
65*4882a593Smuzhiyun #define EC_LPC_CMDR_SCI		(1 << 5)  /* SCI event is pending */
66*4882a593Smuzhiyun #define EC_LPC_CMDR_SMI		(1 << 6)  /* SMI event is pending */
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun #define EC_LPC_ADDR_MEMMAP       0x900
69*4882a593Smuzhiyun #define EC_MEMMAP_SIZE         255 /* ACPI IO buffer max is 255 bytes */
70*4882a593Smuzhiyun #define EC_MEMMAP_TEXT_MAX     8   /* Size of a string in the memory map */
71*4882a593Smuzhiyun 
72*4882a593Smuzhiyun /* The offset address of each type of data in mapped memory. */
73*4882a593Smuzhiyun #define EC_MEMMAP_TEMP_SENSOR      0x00 /* Temp sensors */
74*4882a593Smuzhiyun #define EC_MEMMAP_FAN              0x10 /* Fan speeds */
75*4882a593Smuzhiyun #define EC_MEMMAP_TEMP_SENSOR_B    0x18 /* Temp sensors (second set) */
76*4882a593Smuzhiyun #define EC_MEMMAP_ID               0x20 /* 'E' 'C' */
77*4882a593Smuzhiyun #define EC_MEMMAP_ID_VERSION       0x22 /* Version of data in 0x20 - 0x2f */
78*4882a593Smuzhiyun #define EC_MEMMAP_THERMAL_VERSION  0x23 /* Version of data in 0x00 - 0x1f */
79*4882a593Smuzhiyun #define EC_MEMMAP_BATTERY_VERSION  0x24 /* Version of data in 0x40 - 0x7f */
80*4882a593Smuzhiyun #define EC_MEMMAP_SWITCHES_VERSION 0x25 /* Version of data in 0x30 - 0x33 */
81*4882a593Smuzhiyun #define EC_MEMMAP_EVENTS_VERSION   0x26 /* Version of data in 0x34 - 0x3f */
82*4882a593Smuzhiyun #define EC_MEMMAP_HOST_CMD_FLAGS   0x27 /* Host command interface flags */
83*4882a593Smuzhiyun #define EC_MEMMAP_SWITCHES         0x30
84*4882a593Smuzhiyun #define EC_MEMMAP_HOST_EVENTS      0x34
85*4882a593Smuzhiyun #define EC_MEMMAP_BATT_VOLT        0x40 /* Battery Present Voltage */
86*4882a593Smuzhiyun #define EC_MEMMAP_BATT_RATE        0x44 /* Battery Present Rate */
87*4882a593Smuzhiyun #define EC_MEMMAP_BATT_CAP         0x48 /* Battery Remaining Capacity */
88*4882a593Smuzhiyun #define EC_MEMMAP_BATT_FLAG        0x4c /* Battery State, defined below */
89*4882a593Smuzhiyun #define EC_MEMMAP_BATT_DCAP        0x50 /* Battery Design Capacity */
90*4882a593Smuzhiyun #define EC_MEMMAP_BATT_DVLT        0x54 /* Battery Design Voltage */
91*4882a593Smuzhiyun #define EC_MEMMAP_BATT_LFCC        0x58 /* Battery Last Full Charge Capacity */
92*4882a593Smuzhiyun #define EC_MEMMAP_BATT_CCNT        0x5c /* Battery Cycle Count */
93*4882a593Smuzhiyun #define EC_MEMMAP_BATT_MFGR        0x60 /* Battery Manufacturer String */
94*4882a593Smuzhiyun #define EC_MEMMAP_BATT_MODEL       0x68 /* Battery Model Number String */
95*4882a593Smuzhiyun #define EC_MEMMAP_BATT_SERIAL      0x70 /* Battery Serial Number String */
96*4882a593Smuzhiyun #define EC_MEMMAP_BATT_TYPE        0x78 /* Battery Type String */
97*4882a593Smuzhiyun 
98*4882a593Smuzhiyun /* Number of temp sensors at EC_MEMMAP_TEMP_SENSOR */
99*4882a593Smuzhiyun #define EC_TEMP_SENSOR_ENTRIES     16
100*4882a593Smuzhiyun /*
101*4882a593Smuzhiyun  * Number of temp sensors at EC_MEMMAP_TEMP_SENSOR_B.
102*4882a593Smuzhiyun  *
103*4882a593Smuzhiyun  * Valid only if EC_MEMMAP_THERMAL_VERSION returns >= 2.
104*4882a593Smuzhiyun  */
105*4882a593Smuzhiyun #define EC_TEMP_SENSOR_B_ENTRIES      8
106*4882a593Smuzhiyun #define EC_TEMP_SENSOR_NOT_PRESENT    0xff
107*4882a593Smuzhiyun #define EC_TEMP_SENSOR_ERROR          0xfe
108*4882a593Smuzhiyun #define EC_TEMP_SENSOR_NOT_POWERED    0xfd
109*4882a593Smuzhiyun #define EC_TEMP_SENSOR_NOT_CALIBRATED 0xfc
110*4882a593Smuzhiyun /*
111*4882a593Smuzhiyun  * The offset of temperature value stored in mapped memory.  This allows
112*4882a593Smuzhiyun  * reporting a temperature range of 200K to 454K = -73C to 181C.
113*4882a593Smuzhiyun  */
114*4882a593Smuzhiyun #define EC_TEMP_SENSOR_OFFSET      200
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun #define EC_FAN_SPEED_ENTRIES       4       /* Number of fans at EC_MEMMAP_FAN */
117*4882a593Smuzhiyun #define EC_FAN_SPEED_NOT_PRESENT   0xffff  /* Entry not present */
118*4882a593Smuzhiyun #define EC_FAN_SPEED_STALLED       0xfffe  /* Fan stalled */
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun /* Battery bit flags at EC_MEMMAP_BATT_FLAG. */
121*4882a593Smuzhiyun #define EC_BATT_FLAG_AC_PRESENT   0x01
122*4882a593Smuzhiyun #define EC_BATT_FLAG_BATT_PRESENT 0x02
123*4882a593Smuzhiyun #define EC_BATT_FLAG_DISCHARGING  0x04
124*4882a593Smuzhiyun #define EC_BATT_FLAG_CHARGING     0x08
125*4882a593Smuzhiyun #define EC_BATT_FLAG_LEVEL_CRITICAL 0x10
126*4882a593Smuzhiyun 
127*4882a593Smuzhiyun /* Switch flags at EC_MEMMAP_SWITCHES */
128*4882a593Smuzhiyun #define EC_SWITCH_LID_OPEN               0x01
129*4882a593Smuzhiyun #define EC_SWITCH_POWER_BUTTON_PRESSED   0x02
130*4882a593Smuzhiyun #define EC_SWITCH_WRITE_PROTECT_DISABLED 0x04
131*4882a593Smuzhiyun /* Was recovery requested via keyboard; now unused. */
132*4882a593Smuzhiyun #define EC_SWITCH_IGNORE1		 0x08
133*4882a593Smuzhiyun /* Recovery requested via dedicated signal (from servo board) */
134*4882a593Smuzhiyun #define EC_SWITCH_DEDICATED_RECOVERY     0x10
135*4882a593Smuzhiyun /* Was fake developer mode switch; now unused.  Remove in next refactor. */
136*4882a593Smuzhiyun #define EC_SWITCH_IGNORE0                0x20
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun /* Host command interface flags */
139*4882a593Smuzhiyun /* Host command interface supports LPC args (LPC interface only) */
140*4882a593Smuzhiyun #define EC_HOST_CMD_FLAG_LPC_ARGS_SUPPORTED  0x01
141*4882a593Smuzhiyun /* Host command interface supports version 3 protocol */
142*4882a593Smuzhiyun #define EC_HOST_CMD_FLAG_VERSION_3   0x02
143*4882a593Smuzhiyun 
144*4882a593Smuzhiyun /* Wireless switch flags */
145*4882a593Smuzhiyun #define EC_WIRELESS_SWITCH_WLAN      0x01
146*4882a593Smuzhiyun #define EC_WIRELESS_SWITCH_BLUETOOTH 0x02
147*4882a593Smuzhiyun #define EC_WIRELESS_SWITCH_WWAN      0x04
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun /*
150*4882a593Smuzhiyun  * This header file is used in coreboot both in C and ACPI code.  The ACPI code
151*4882a593Smuzhiyun  * is pre-processed to handle constants but the ASL compiler is unable to
152*4882a593Smuzhiyun  * handle actual C code so keep it separate.
153*4882a593Smuzhiyun  */
154*4882a593Smuzhiyun #ifndef __ACPI__
155*4882a593Smuzhiyun 
156*4882a593Smuzhiyun /*
157*4882a593Smuzhiyun  * Define __packed if someone hasn't beat us to it.  Linux kernel style
158*4882a593Smuzhiyun  * checking prefers __packed over __attribute__((packed)).
159*4882a593Smuzhiyun  */
160*4882a593Smuzhiyun #ifndef __packed
161*4882a593Smuzhiyun #define __packed __attribute__((packed))
162*4882a593Smuzhiyun #endif
163*4882a593Smuzhiyun 
164*4882a593Smuzhiyun /* LPC command status byte masks */
165*4882a593Smuzhiyun /* EC has written a byte in the data register and host hasn't read it yet */
166*4882a593Smuzhiyun #define EC_LPC_STATUS_TO_HOST     0x01
167*4882a593Smuzhiyun /* Host has written a command/data byte and the EC hasn't read it yet */
168*4882a593Smuzhiyun #define EC_LPC_STATUS_FROM_HOST   0x02
169*4882a593Smuzhiyun /* EC is processing a command */
170*4882a593Smuzhiyun #define EC_LPC_STATUS_PROCESSING  0x04
171*4882a593Smuzhiyun /* Last write to EC was a command, not data */
172*4882a593Smuzhiyun #define EC_LPC_STATUS_LAST_CMD    0x08
173*4882a593Smuzhiyun /* EC is in burst mode.  Unsupported by Chrome EC, so this bit is never set */
174*4882a593Smuzhiyun #define EC_LPC_STATUS_BURST_MODE  0x10
175*4882a593Smuzhiyun /* SCI event is pending (requesting SCI query) */
176*4882a593Smuzhiyun #define EC_LPC_STATUS_SCI_PENDING 0x20
177*4882a593Smuzhiyun /* SMI event is pending (requesting SMI query) */
178*4882a593Smuzhiyun #define EC_LPC_STATUS_SMI_PENDING 0x40
179*4882a593Smuzhiyun /* (reserved) */
180*4882a593Smuzhiyun #define EC_LPC_STATUS_RESERVED    0x80
181*4882a593Smuzhiyun 
182*4882a593Smuzhiyun /*
183*4882a593Smuzhiyun  * EC is busy.  This covers both the EC processing a command, and the host has
184*4882a593Smuzhiyun  * written a new command but the EC hasn't picked it up yet.
185*4882a593Smuzhiyun  */
186*4882a593Smuzhiyun #define EC_LPC_STATUS_BUSY_MASK \
187*4882a593Smuzhiyun 	(EC_LPC_STATUS_FROM_HOST | EC_LPC_STATUS_PROCESSING)
188*4882a593Smuzhiyun 
189*4882a593Smuzhiyun /* Host command response codes */
190*4882a593Smuzhiyun enum ec_status {
191*4882a593Smuzhiyun 	EC_RES_SUCCESS = 0,
192*4882a593Smuzhiyun 	EC_RES_INVALID_COMMAND = 1,
193*4882a593Smuzhiyun 	EC_RES_ERROR = 2,
194*4882a593Smuzhiyun 	EC_RES_INVALID_PARAM = 3,
195*4882a593Smuzhiyun 	EC_RES_ACCESS_DENIED = 4,
196*4882a593Smuzhiyun 	EC_RES_INVALID_RESPONSE = 5,
197*4882a593Smuzhiyun 	EC_RES_INVALID_VERSION = 6,
198*4882a593Smuzhiyun 	EC_RES_INVALID_CHECKSUM = 7,
199*4882a593Smuzhiyun 	EC_RES_IN_PROGRESS = 8,		/* Accepted, command in progress */
200*4882a593Smuzhiyun 	EC_RES_UNAVAILABLE = 9,		/* No response available */
201*4882a593Smuzhiyun 	EC_RES_TIMEOUT = 10,		/* We got a timeout */
202*4882a593Smuzhiyun 	EC_RES_OVERFLOW = 11,		/* Table / data overflow */
203*4882a593Smuzhiyun 	EC_RES_INVALID_HEADER = 12,     /* Header contains invalid data */
204*4882a593Smuzhiyun 	EC_RES_REQUEST_TRUNCATED = 13,  /* Didn't get the entire request */
205*4882a593Smuzhiyun 	EC_RES_RESPONSE_TOO_BIG = 14    /* Response was too big to handle */
206*4882a593Smuzhiyun };
207*4882a593Smuzhiyun 
208*4882a593Smuzhiyun /*
209*4882a593Smuzhiyun  * Host event codes.  Note these are 1-based, not 0-based, because ACPI query
210*4882a593Smuzhiyun  * EC command uses code 0 to mean "no event pending".  We explicitly specify
211*4882a593Smuzhiyun  * each value in the enum listing so they won't change if we delete/insert an
212*4882a593Smuzhiyun  * item or rearrange the list (it needs to be stable across platforms, not
213*4882a593Smuzhiyun  * just within a single compiled instance).
214*4882a593Smuzhiyun  */
215*4882a593Smuzhiyun enum host_event_code {
216*4882a593Smuzhiyun 	EC_HOST_EVENT_LID_CLOSED = 1,
217*4882a593Smuzhiyun 	EC_HOST_EVENT_LID_OPEN = 2,
218*4882a593Smuzhiyun 	EC_HOST_EVENT_POWER_BUTTON = 3,
219*4882a593Smuzhiyun 	EC_HOST_EVENT_AC_CONNECTED = 4,
220*4882a593Smuzhiyun 	EC_HOST_EVENT_AC_DISCONNECTED = 5,
221*4882a593Smuzhiyun 	EC_HOST_EVENT_BATTERY_LOW = 6,
222*4882a593Smuzhiyun 	EC_HOST_EVENT_BATTERY_CRITICAL = 7,
223*4882a593Smuzhiyun 	EC_HOST_EVENT_BATTERY = 8,
224*4882a593Smuzhiyun 	EC_HOST_EVENT_THERMAL_THRESHOLD = 9,
225*4882a593Smuzhiyun 	EC_HOST_EVENT_THERMAL_OVERLOAD = 10,
226*4882a593Smuzhiyun 	EC_HOST_EVENT_THERMAL = 11,
227*4882a593Smuzhiyun 	EC_HOST_EVENT_USB_CHARGER = 12,
228*4882a593Smuzhiyun 	EC_HOST_EVENT_KEY_PRESSED = 13,
229*4882a593Smuzhiyun 	/*
230*4882a593Smuzhiyun 	 * EC has finished initializing the host interface.  The host can check
231*4882a593Smuzhiyun 	 * for this event following sending a EC_CMD_REBOOT_EC command to
232*4882a593Smuzhiyun 	 * determine when the EC is ready to accept subsequent commands.
233*4882a593Smuzhiyun 	 */
234*4882a593Smuzhiyun 	EC_HOST_EVENT_INTERFACE_READY = 14,
235*4882a593Smuzhiyun 	/* Keyboard recovery combo has been pressed */
236*4882a593Smuzhiyun 	EC_HOST_EVENT_KEYBOARD_RECOVERY = 15,
237*4882a593Smuzhiyun 
238*4882a593Smuzhiyun 	/* Shutdown due to thermal overload */
239*4882a593Smuzhiyun 	EC_HOST_EVENT_THERMAL_SHUTDOWN = 16,
240*4882a593Smuzhiyun 	/* Shutdown due to battery level too low */
241*4882a593Smuzhiyun 	EC_HOST_EVENT_BATTERY_SHUTDOWN = 17,
242*4882a593Smuzhiyun 
243*4882a593Smuzhiyun 	/*
244*4882a593Smuzhiyun 	 * The high bit of the event mask is not used as a host event code.  If
245*4882a593Smuzhiyun 	 * it reads back as set, then the entire event mask should be
246*4882a593Smuzhiyun 	 * considered invalid by the host.  This can happen when reading the
247*4882a593Smuzhiyun 	 * raw event status via EC_MEMMAP_HOST_EVENTS but the LPC interface is
248*4882a593Smuzhiyun 	 * not initialized on the EC, or improperly configured on the host.
249*4882a593Smuzhiyun 	 */
250*4882a593Smuzhiyun 	EC_HOST_EVENT_INVALID = 32
251*4882a593Smuzhiyun };
252*4882a593Smuzhiyun /* Host event mask */
253*4882a593Smuzhiyun #define EC_HOST_EVENT_MASK(event_code) (1UL << ((event_code) - 1))
254*4882a593Smuzhiyun 
255*4882a593Smuzhiyun /* Arguments at EC_LPC_ADDR_HOST_ARGS */
256*4882a593Smuzhiyun struct ec_lpc_host_args {
257*4882a593Smuzhiyun 	uint8_t flags;
258*4882a593Smuzhiyun 	uint8_t command_version;
259*4882a593Smuzhiyun 	uint8_t data_size;
260*4882a593Smuzhiyun 	/*
261*4882a593Smuzhiyun 	 * Checksum; sum of command + flags + command_version + data_size +
262*4882a593Smuzhiyun 	 * all params/response data bytes.
263*4882a593Smuzhiyun 	 */
264*4882a593Smuzhiyun 	uint8_t checksum;
265*4882a593Smuzhiyun } __packed;
266*4882a593Smuzhiyun 
267*4882a593Smuzhiyun /* Flags for ec_lpc_host_args.flags */
268*4882a593Smuzhiyun /*
269*4882a593Smuzhiyun  * Args are from host.  Data area at EC_LPC_ADDR_HOST_PARAM contains command
270*4882a593Smuzhiyun  * params.
271*4882a593Smuzhiyun  *
272*4882a593Smuzhiyun  * If EC gets a command and this flag is not set, this is an old-style command.
273*4882a593Smuzhiyun  * Command version is 0 and params from host are at EC_LPC_ADDR_OLD_PARAM with
274*4882a593Smuzhiyun  * unknown length.  EC must respond with an old-style response (that is,
275*4882a593Smuzhiyun  * withouth setting EC_HOST_ARGS_FLAG_TO_HOST).
276*4882a593Smuzhiyun  */
277*4882a593Smuzhiyun #define EC_HOST_ARGS_FLAG_FROM_HOST 0x01
278*4882a593Smuzhiyun /*
279*4882a593Smuzhiyun  * Args are from EC.  Data area at EC_LPC_ADDR_HOST_PARAM contains response.
280*4882a593Smuzhiyun  *
281*4882a593Smuzhiyun  * If EC responds to a command and this flag is not set, this is an old-style
282*4882a593Smuzhiyun  * response.  Command version is 0 and response data from EC is at
283*4882a593Smuzhiyun  * EC_LPC_ADDR_OLD_PARAM with unknown length.
284*4882a593Smuzhiyun  */
285*4882a593Smuzhiyun #define EC_HOST_ARGS_FLAG_TO_HOST   0x02
286*4882a593Smuzhiyun 
287*4882a593Smuzhiyun /*****************************************************************************/
288*4882a593Smuzhiyun 
289*4882a593Smuzhiyun /*
290*4882a593Smuzhiyun  * Protocol version 2 for I2C and SPI send a request this way:
291*4882a593Smuzhiyun  *
292*4882a593Smuzhiyun  *	0	EC_CMD_VERSION0 + (command version)
293*4882a593Smuzhiyun  *	1	Command number
294*4882a593Smuzhiyun  *	2	Length of params = N
295*4882a593Smuzhiyun  *	3..N+2	Params, if any
296*4882a593Smuzhiyun  *	N+3	8-bit checksum of bytes 0..N+2
297*4882a593Smuzhiyun  *
298*4882a593Smuzhiyun  * The corresponding response is:
299*4882a593Smuzhiyun  *
300*4882a593Smuzhiyun  *	0	Result code (EC_RES_*)
301*4882a593Smuzhiyun  *	1	Length of params = M
302*4882a593Smuzhiyun  *	2..M+1	Params, if any
303*4882a593Smuzhiyun  *	M+2	8-bit checksum of bytes 0..M+1
304*4882a593Smuzhiyun  */
305*4882a593Smuzhiyun #define EC_PROTO2_REQUEST_HEADER_BYTES 3
306*4882a593Smuzhiyun #define EC_PROTO2_REQUEST_TRAILER_BYTES 1
307*4882a593Smuzhiyun #define EC_PROTO2_REQUEST_OVERHEAD (EC_PROTO2_REQUEST_HEADER_BYTES +	\
308*4882a593Smuzhiyun 				    EC_PROTO2_REQUEST_TRAILER_BYTES)
309*4882a593Smuzhiyun 
310*4882a593Smuzhiyun #define EC_PROTO2_RESPONSE_HEADER_BYTES 2
311*4882a593Smuzhiyun #define EC_PROTO2_RESPONSE_TRAILER_BYTES 1
312*4882a593Smuzhiyun #define EC_PROTO2_RESPONSE_OVERHEAD (EC_PROTO2_RESPONSE_HEADER_BYTES +	\
313*4882a593Smuzhiyun 				     EC_PROTO2_RESPONSE_TRAILER_BYTES)
314*4882a593Smuzhiyun 
315*4882a593Smuzhiyun /* Parameter length was limited by the LPC interface */
316*4882a593Smuzhiyun #define EC_PROTO2_MAX_PARAM_SIZE 0xfc
317*4882a593Smuzhiyun 
318*4882a593Smuzhiyun /* Maximum request and response packet sizes for protocol version 2 */
319*4882a593Smuzhiyun #define EC_PROTO2_MAX_REQUEST_SIZE (EC_PROTO2_REQUEST_OVERHEAD +	\
320*4882a593Smuzhiyun 				    EC_PROTO2_MAX_PARAM_SIZE)
321*4882a593Smuzhiyun #define EC_PROTO2_MAX_RESPONSE_SIZE (EC_PROTO2_RESPONSE_OVERHEAD +	\
322*4882a593Smuzhiyun 				     EC_PROTO2_MAX_PARAM_SIZE)
323*4882a593Smuzhiyun 
324*4882a593Smuzhiyun /*****************************************************************************/
325*4882a593Smuzhiyun 
326*4882a593Smuzhiyun /*
327*4882a593Smuzhiyun  * Value written to legacy command port / prefix byte to indicate protocol
328*4882a593Smuzhiyun  * 3+ structs are being used.  Usage is bus-dependent.
329*4882a593Smuzhiyun  */
330*4882a593Smuzhiyun #define EC_COMMAND_PROTOCOL_3 0xda
331*4882a593Smuzhiyun 
332*4882a593Smuzhiyun #define EC_HOST_REQUEST_VERSION 3
333*4882a593Smuzhiyun 
334*4882a593Smuzhiyun /* Version 3 request from host */
335*4882a593Smuzhiyun struct ec_host_request {
336*4882a593Smuzhiyun 	/* Struct version (=3)
337*4882a593Smuzhiyun 	 *
338*4882a593Smuzhiyun 	 * EC will return EC_RES_INVALID_HEADER if it receives a header with a
339*4882a593Smuzhiyun 	 * version it doesn't know how to parse.
340*4882a593Smuzhiyun 	 */
341*4882a593Smuzhiyun 	uint8_t struct_version;
342*4882a593Smuzhiyun 
343*4882a593Smuzhiyun 	/*
344*4882a593Smuzhiyun 	 * Checksum of request and data; sum of all bytes including checksum
345*4882a593Smuzhiyun 	 * should total to 0.
346*4882a593Smuzhiyun 	 */
347*4882a593Smuzhiyun 	uint8_t checksum;
348*4882a593Smuzhiyun 
349*4882a593Smuzhiyun 	/* Command code */
350*4882a593Smuzhiyun 	uint16_t command;
351*4882a593Smuzhiyun 
352*4882a593Smuzhiyun 	/* Command version */
353*4882a593Smuzhiyun 	uint8_t command_version;
354*4882a593Smuzhiyun 
355*4882a593Smuzhiyun 	/* Unused byte in current protocol version; set to 0 */
356*4882a593Smuzhiyun 	uint8_t reserved;
357*4882a593Smuzhiyun 
358*4882a593Smuzhiyun 	/* Length of data which follows this header */
359*4882a593Smuzhiyun 	uint16_t data_len;
360*4882a593Smuzhiyun } __packed;
361*4882a593Smuzhiyun 
362*4882a593Smuzhiyun #define EC_HOST_RESPONSE_VERSION 3
363*4882a593Smuzhiyun 
364*4882a593Smuzhiyun /* Version 3 response from EC */
365*4882a593Smuzhiyun struct ec_host_response {
366*4882a593Smuzhiyun 	/* Struct version (=3) */
367*4882a593Smuzhiyun 	uint8_t struct_version;
368*4882a593Smuzhiyun 
369*4882a593Smuzhiyun 	/*
370*4882a593Smuzhiyun 	 * Checksum of response and data; sum of all bytes including checksum
371*4882a593Smuzhiyun 	 * should total to 0.
372*4882a593Smuzhiyun 	 */
373*4882a593Smuzhiyun 	uint8_t checksum;
374*4882a593Smuzhiyun 
375*4882a593Smuzhiyun 	/* Result code (EC_RES_*) */
376*4882a593Smuzhiyun 	uint16_t result;
377*4882a593Smuzhiyun 
378*4882a593Smuzhiyun 	/* Length of data which follows this header */
379*4882a593Smuzhiyun 	uint16_t data_len;
380*4882a593Smuzhiyun 
381*4882a593Smuzhiyun 	/* Unused bytes in current protocol version; set to 0 */
382*4882a593Smuzhiyun 	uint16_t reserved;
383*4882a593Smuzhiyun } __packed;
384*4882a593Smuzhiyun 
385*4882a593Smuzhiyun /*****************************************************************************/
386*4882a593Smuzhiyun /*
387*4882a593Smuzhiyun  * Notes on commands:
388*4882a593Smuzhiyun  *
389*4882a593Smuzhiyun  * Each command is an 8-byte command value.  Commands which take params or
390*4882a593Smuzhiyun  * return response data specify structs for that data.  If no struct is
391*4882a593Smuzhiyun  * specified, the command does not input or output data, respectively.
392*4882a593Smuzhiyun  * Parameter/response length is implicit in the structs.  Some underlying
393*4882a593Smuzhiyun  * communication protocols (I2C, SPI) may add length or checksum headers, but
394*4882a593Smuzhiyun  * those are implementation-dependent and not defined here.
395*4882a593Smuzhiyun  */
396*4882a593Smuzhiyun 
397*4882a593Smuzhiyun /*****************************************************************************/
398*4882a593Smuzhiyun /* General / test commands */
399*4882a593Smuzhiyun 
400*4882a593Smuzhiyun /*
401*4882a593Smuzhiyun  * Get protocol version, used to deal with non-backward compatible protocol
402*4882a593Smuzhiyun  * changes.
403*4882a593Smuzhiyun  */
404*4882a593Smuzhiyun #define EC_CMD_PROTO_VERSION 0x00
405*4882a593Smuzhiyun 
406*4882a593Smuzhiyun struct ec_response_proto_version {
407*4882a593Smuzhiyun 	uint32_t version;
408*4882a593Smuzhiyun } __packed;
409*4882a593Smuzhiyun 
410*4882a593Smuzhiyun /*
411*4882a593Smuzhiyun  * Hello.  This is a simple command to test the EC is responsive to
412*4882a593Smuzhiyun  * commands.
413*4882a593Smuzhiyun  */
414*4882a593Smuzhiyun #define EC_CMD_HELLO 0x01
415*4882a593Smuzhiyun 
416*4882a593Smuzhiyun struct ec_params_hello {
417*4882a593Smuzhiyun 	uint32_t in_data;  /* Pass anything here */
418*4882a593Smuzhiyun } __packed;
419*4882a593Smuzhiyun 
420*4882a593Smuzhiyun struct ec_response_hello {
421*4882a593Smuzhiyun 	uint32_t out_data;  /* Output will be in_data + 0x01020304 */
422*4882a593Smuzhiyun } __packed;
423*4882a593Smuzhiyun 
424*4882a593Smuzhiyun /* Get version number */
425*4882a593Smuzhiyun #define EC_CMD_GET_VERSION 0x02
426*4882a593Smuzhiyun 
427*4882a593Smuzhiyun enum ec_current_image {
428*4882a593Smuzhiyun 	EC_IMAGE_UNKNOWN = 0,
429*4882a593Smuzhiyun 	EC_IMAGE_RO,
430*4882a593Smuzhiyun 	EC_IMAGE_RW
431*4882a593Smuzhiyun };
432*4882a593Smuzhiyun 
433*4882a593Smuzhiyun struct ec_response_get_version {
434*4882a593Smuzhiyun 	/* Null-terminated version strings for RO, RW */
435*4882a593Smuzhiyun 	char version_string_ro[32];
436*4882a593Smuzhiyun 	char version_string_rw[32];
437*4882a593Smuzhiyun 	char reserved[32];       /* Was previously RW-B string */
438*4882a593Smuzhiyun 	uint32_t current_image;  /* One of ec_current_image */
439*4882a593Smuzhiyun } __packed;
440*4882a593Smuzhiyun 
441*4882a593Smuzhiyun /* Read test */
442*4882a593Smuzhiyun #define EC_CMD_READ_TEST 0x03
443*4882a593Smuzhiyun 
444*4882a593Smuzhiyun struct ec_params_read_test {
445*4882a593Smuzhiyun 	uint32_t offset;   /* Starting value for read buffer */
446*4882a593Smuzhiyun 	uint32_t size;     /* Size to read in bytes */
447*4882a593Smuzhiyun } __packed;
448*4882a593Smuzhiyun 
449*4882a593Smuzhiyun struct ec_response_read_test {
450*4882a593Smuzhiyun 	uint32_t data[32];
451*4882a593Smuzhiyun } __packed;
452*4882a593Smuzhiyun 
453*4882a593Smuzhiyun /*
454*4882a593Smuzhiyun  * Get build information
455*4882a593Smuzhiyun  *
456*4882a593Smuzhiyun  * Response is null-terminated string.
457*4882a593Smuzhiyun  */
458*4882a593Smuzhiyun #define EC_CMD_GET_BUILD_INFO 0x04
459*4882a593Smuzhiyun 
460*4882a593Smuzhiyun /* Get chip info */
461*4882a593Smuzhiyun #define EC_CMD_GET_CHIP_INFO 0x05
462*4882a593Smuzhiyun 
463*4882a593Smuzhiyun struct ec_response_get_chip_info {
464*4882a593Smuzhiyun 	/* Null-terminated strings */
465*4882a593Smuzhiyun 	char vendor[32];
466*4882a593Smuzhiyun 	char name[32];
467*4882a593Smuzhiyun 	char revision[32];  /* Mask version */
468*4882a593Smuzhiyun } __packed;
469*4882a593Smuzhiyun 
470*4882a593Smuzhiyun /* Get board HW version */
471*4882a593Smuzhiyun #define EC_CMD_GET_BOARD_VERSION 0x06
472*4882a593Smuzhiyun 
473*4882a593Smuzhiyun struct ec_response_board_version {
474*4882a593Smuzhiyun 	uint16_t board_version;  /* A monotonously incrementing number. */
475*4882a593Smuzhiyun } __packed;
476*4882a593Smuzhiyun 
477*4882a593Smuzhiyun /*
478*4882a593Smuzhiyun  * Read memory-mapped data.
479*4882a593Smuzhiyun  *
480*4882a593Smuzhiyun  * This is an alternate interface to memory-mapped data for bus protocols
481*4882a593Smuzhiyun  * which don't support direct-mapped memory - I2C, SPI, etc.
482*4882a593Smuzhiyun  *
483*4882a593Smuzhiyun  * Response is params.size bytes of data.
484*4882a593Smuzhiyun  */
485*4882a593Smuzhiyun #define EC_CMD_READ_MEMMAP 0x07
486*4882a593Smuzhiyun 
487*4882a593Smuzhiyun struct ec_params_read_memmap {
488*4882a593Smuzhiyun 	uint8_t offset;   /* Offset in memmap (EC_MEMMAP_*) */
489*4882a593Smuzhiyun 	uint8_t size;     /* Size to read in bytes */
490*4882a593Smuzhiyun } __packed;
491*4882a593Smuzhiyun 
492*4882a593Smuzhiyun /* Read versions supported for a command */
493*4882a593Smuzhiyun #define EC_CMD_GET_CMD_VERSIONS 0x08
494*4882a593Smuzhiyun 
495*4882a593Smuzhiyun struct ec_params_get_cmd_versions {
496*4882a593Smuzhiyun 	uint8_t cmd;      /* Command to check */
497*4882a593Smuzhiyun } __packed;
498*4882a593Smuzhiyun 
499*4882a593Smuzhiyun struct ec_response_get_cmd_versions {
500*4882a593Smuzhiyun 	/*
501*4882a593Smuzhiyun 	 * Mask of supported versions; use EC_VER_MASK() to compare with a
502*4882a593Smuzhiyun 	 * desired version.
503*4882a593Smuzhiyun 	 */
504*4882a593Smuzhiyun 	uint32_t version_mask;
505*4882a593Smuzhiyun } __packed;
506*4882a593Smuzhiyun 
507*4882a593Smuzhiyun /*
508*4882a593Smuzhiyun  * Check EC communcations status (busy). This is needed on i2c/spi but not
509*4882a593Smuzhiyun  * on lpc since it has its own out-of-band busy indicator.
510*4882a593Smuzhiyun  *
511*4882a593Smuzhiyun  * lpc must read the status from the command register. Attempting this on
512*4882a593Smuzhiyun  * lpc will overwrite the args/parameter space and corrupt its data.
513*4882a593Smuzhiyun  */
514*4882a593Smuzhiyun #define EC_CMD_GET_COMMS_STATUS		0x09
515*4882a593Smuzhiyun 
516*4882a593Smuzhiyun /* Avoid using ec_status which is for return values */
517*4882a593Smuzhiyun enum ec_comms_status {
518*4882a593Smuzhiyun 	EC_COMMS_STATUS_PROCESSING	= 1 << 0,	/* Processing cmd */
519*4882a593Smuzhiyun };
520*4882a593Smuzhiyun 
521*4882a593Smuzhiyun struct ec_response_get_comms_status {
522*4882a593Smuzhiyun 	uint32_t flags;		/* Mask of enum ec_comms_status */
523*4882a593Smuzhiyun } __packed;
524*4882a593Smuzhiyun 
525*4882a593Smuzhiyun /*
526*4882a593Smuzhiyun  * Fake a variety of responses, purely for testing purposes.
527*4882a593Smuzhiyun  * FIXME: Would be nice to force checksum errors.
528*4882a593Smuzhiyun  */
529*4882a593Smuzhiyun #define EC_CMD_TEST_PROTOCOL		0x0a
530*4882a593Smuzhiyun 
531*4882a593Smuzhiyun /* Tell the EC what to send back to us. */
532*4882a593Smuzhiyun struct ec_params_test_protocol {
533*4882a593Smuzhiyun 	uint32_t ec_result;
534*4882a593Smuzhiyun 	uint32_t ret_len;
535*4882a593Smuzhiyun 	uint8_t buf[32];
536*4882a593Smuzhiyun } __packed;
537*4882a593Smuzhiyun 
538*4882a593Smuzhiyun /* Here it comes... */
539*4882a593Smuzhiyun struct ec_response_test_protocol {
540*4882a593Smuzhiyun 	uint8_t buf[32];
541*4882a593Smuzhiyun } __packed;
542*4882a593Smuzhiyun 
543*4882a593Smuzhiyun /* Get prococol information */
544*4882a593Smuzhiyun #define EC_CMD_GET_PROTOCOL_INFO	0x0b
545*4882a593Smuzhiyun 
546*4882a593Smuzhiyun /* Flags for ec_response_get_protocol_info.flags */
547*4882a593Smuzhiyun /* EC_RES_IN_PROGRESS may be returned if a command is slow */
548*4882a593Smuzhiyun #define EC_PROTOCOL_INFO_IN_PROGRESS_SUPPORTED (1 << 0)
549*4882a593Smuzhiyun 
550*4882a593Smuzhiyun struct ec_response_get_protocol_info {
551*4882a593Smuzhiyun 	/* Fields which exist if at least protocol version 3 supported */
552*4882a593Smuzhiyun 
553*4882a593Smuzhiyun 	/* Bitmask of protocol versions supported (1 << n means version n)*/
554*4882a593Smuzhiyun 	uint32_t protocol_versions;
555*4882a593Smuzhiyun 
556*4882a593Smuzhiyun 	/* Maximum request packet size, in bytes */
557*4882a593Smuzhiyun 	uint16_t max_request_packet_size;
558*4882a593Smuzhiyun 
559*4882a593Smuzhiyun 	/* Maximum response packet size, in bytes */
560*4882a593Smuzhiyun 	uint16_t max_response_packet_size;
561*4882a593Smuzhiyun 
562*4882a593Smuzhiyun 	/* Flags; see EC_PROTOCOL_INFO_* */
563*4882a593Smuzhiyun 	uint32_t flags;
564*4882a593Smuzhiyun } __packed;
565*4882a593Smuzhiyun 
566*4882a593Smuzhiyun /*****************************************************************************/
567*4882a593Smuzhiyun /* Flash commands */
568*4882a593Smuzhiyun 
569*4882a593Smuzhiyun /* Get flash info */
570*4882a593Smuzhiyun #define EC_CMD_FLASH_INFO 0x10
571*4882a593Smuzhiyun 
572*4882a593Smuzhiyun struct ec_response_flash_info {
573*4882a593Smuzhiyun 	/* Usable flash size, in bytes */
574*4882a593Smuzhiyun 	uint32_t flash_size;
575*4882a593Smuzhiyun 	/*
576*4882a593Smuzhiyun 	 * Write block size.  Write offset and size must be a multiple
577*4882a593Smuzhiyun 	 * of this.
578*4882a593Smuzhiyun 	 */
579*4882a593Smuzhiyun 	uint32_t write_block_size;
580*4882a593Smuzhiyun 	/*
581*4882a593Smuzhiyun 	 * Erase block size.  Erase offset and size must be a multiple
582*4882a593Smuzhiyun 	 * of this.
583*4882a593Smuzhiyun 	 */
584*4882a593Smuzhiyun 	uint32_t erase_block_size;
585*4882a593Smuzhiyun 	/*
586*4882a593Smuzhiyun 	 * Protection block size.  Protection offset and size must be a
587*4882a593Smuzhiyun 	 * multiple of this.
588*4882a593Smuzhiyun 	 */
589*4882a593Smuzhiyun 	uint32_t protect_block_size;
590*4882a593Smuzhiyun } __packed;
591*4882a593Smuzhiyun 
592*4882a593Smuzhiyun /*
593*4882a593Smuzhiyun  * Read flash
594*4882a593Smuzhiyun  *
595*4882a593Smuzhiyun  * Response is params.size bytes of data.
596*4882a593Smuzhiyun  */
597*4882a593Smuzhiyun #define EC_CMD_FLASH_READ 0x11
598*4882a593Smuzhiyun 
599*4882a593Smuzhiyun struct ec_params_flash_read {
600*4882a593Smuzhiyun 	uint32_t offset;   /* Byte offset to read */
601*4882a593Smuzhiyun 	uint32_t size;     /* Size to read in bytes */
602*4882a593Smuzhiyun } __packed;
603*4882a593Smuzhiyun 
604*4882a593Smuzhiyun /* Write flash */
605*4882a593Smuzhiyun #define EC_CMD_FLASH_WRITE 0x12
606*4882a593Smuzhiyun #define EC_VER_FLASH_WRITE 1
607*4882a593Smuzhiyun 
608*4882a593Smuzhiyun /* Version 0 of the flash command supported only 64 bytes of data */
609*4882a593Smuzhiyun #define EC_FLASH_WRITE_VER0_SIZE 64
610*4882a593Smuzhiyun 
611*4882a593Smuzhiyun struct ec_params_flash_write {
612*4882a593Smuzhiyun 	uint32_t offset;   /* Byte offset to write */
613*4882a593Smuzhiyun 	uint32_t size;     /* Size to write in bytes */
614*4882a593Smuzhiyun 	/* Followed by data to write */
615*4882a593Smuzhiyun } __packed;
616*4882a593Smuzhiyun 
617*4882a593Smuzhiyun /* Erase flash */
618*4882a593Smuzhiyun #define EC_CMD_FLASH_ERASE 0x13
619*4882a593Smuzhiyun 
620*4882a593Smuzhiyun struct ec_params_flash_erase {
621*4882a593Smuzhiyun 	uint32_t offset;   /* Byte offset to erase */
622*4882a593Smuzhiyun 	uint32_t size;     /* Size to erase in bytes */
623*4882a593Smuzhiyun } __packed;
624*4882a593Smuzhiyun 
625*4882a593Smuzhiyun /*
626*4882a593Smuzhiyun  * Get/set flash protection.
627*4882a593Smuzhiyun  *
628*4882a593Smuzhiyun  * If mask!=0, sets/clear the requested bits of flags.  Depending on the
629*4882a593Smuzhiyun  * firmware write protect GPIO, not all flags will take effect immediately;
630*4882a593Smuzhiyun  * some flags require a subsequent hard reset to take effect.  Check the
631*4882a593Smuzhiyun  * returned flags bits to see what actually happened.
632*4882a593Smuzhiyun  *
633*4882a593Smuzhiyun  * If mask=0, simply returns the current flags state.
634*4882a593Smuzhiyun  */
635*4882a593Smuzhiyun #define EC_CMD_FLASH_PROTECT 0x15
636*4882a593Smuzhiyun #define EC_VER_FLASH_PROTECT 1  /* Command version 1 */
637*4882a593Smuzhiyun 
638*4882a593Smuzhiyun /* Flags for flash protection */
639*4882a593Smuzhiyun /* RO flash code protected when the EC boots */
640*4882a593Smuzhiyun #define EC_FLASH_PROTECT_RO_AT_BOOT         (1 << 0)
641*4882a593Smuzhiyun /*
642*4882a593Smuzhiyun  * RO flash code protected now.  If this bit is set, at-boot status cannot
643*4882a593Smuzhiyun  * be changed.
644*4882a593Smuzhiyun  */
645*4882a593Smuzhiyun #define EC_FLASH_PROTECT_RO_NOW             (1 << 1)
646*4882a593Smuzhiyun /* Entire flash code protected now, until reboot. */
647*4882a593Smuzhiyun #define EC_FLASH_PROTECT_ALL_NOW            (1 << 2)
648*4882a593Smuzhiyun /* Flash write protect GPIO is asserted now */
649*4882a593Smuzhiyun #define EC_FLASH_PROTECT_GPIO_ASSERTED      (1 << 3)
650*4882a593Smuzhiyun /* Error - at least one bank of flash is stuck locked, and cannot be unlocked */
651*4882a593Smuzhiyun #define EC_FLASH_PROTECT_ERROR_STUCK        (1 << 4)
652*4882a593Smuzhiyun /*
653*4882a593Smuzhiyun  * Error - flash protection is in inconsistent state.  At least one bank of
654*4882a593Smuzhiyun  * flash which should be protected is not protected.  Usually fixed by
655*4882a593Smuzhiyun  * re-requesting the desired flags, or by a hard reset if that fails.
656*4882a593Smuzhiyun  */
657*4882a593Smuzhiyun #define EC_FLASH_PROTECT_ERROR_INCONSISTENT (1 << 5)
658*4882a593Smuzhiyun /* Entile flash code protected when the EC boots */
659*4882a593Smuzhiyun #define EC_FLASH_PROTECT_ALL_AT_BOOT        (1 << 6)
660*4882a593Smuzhiyun 
661*4882a593Smuzhiyun struct ec_params_flash_protect {
662*4882a593Smuzhiyun 	uint32_t mask;   /* Bits in flags to apply */
663*4882a593Smuzhiyun 	uint32_t flags;  /* New flags to apply */
664*4882a593Smuzhiyun } __packed;
665*4882a593Smuzhiyun 
666*4882a593Smuzhiyun struct ec_response_flash_protect {
667*4882a593Smuzhiyun 	/* Current value of flash protect flags */
668*4882a593Smuzhiyun 	uint32_t flags;
669*4882a593Smuzhiyun 	/*
670*4882a593Smuzhiyun 	 * Flags which are valid on this platform.  This allows the caller
671*4882a593Smuzhiyun 	 * to distinguish between flags which aren't set vs. flags which can't
672*4882a593Smuzhiyun 	 * be set on this platform.
673*4882a593Smuzhiyun 	 */
674*4882a593Smuzhiyun 	uint32_t valid_flags;
675*4882a593Smuzhiyun 	/* Flags which can be changed given the current protection state */
676*4882a593Smuzhiyun 	uint32_t writable_flags;
677*4882a593Smuzhiyun } __packed;
678*4882a593Smuzhiyun 
679*4882a593Smuzhiyun /*
680*4882a593Smuzhiyun  * Note: commands 0x14 - 0x19 version 0 were old commands to get/set flash
681*4882a593Smuzhiyun  * write protect.  These commands may be reused with version > 0.
682*4882a593Smuzhiyun  */
683*4882a593Smuzhiyun 
684*4882a593Smuzhiyun /* Get the region offset/size */
685*4882a593Smuzhiyun #define EC_CMD_FLASH_REGION_INFO 0x16
686*4882a593Smuzhiyun #define EC_VER_FLASH_REGION_INFO 1
687*4882a593Smuzhiyun 
688*4882a593Smuzhiyun enum ec_flash_region {
689*4882a593Smuzhiyun 	/* Region which holds read-only EC image */
690*4882a593Smuzhiyun 	EC_FLASH_REGION_RO = 0,
691*4882a593Smuzhiyun 	/* Region which holds rewritable EC image */
692*4882a593Smuzhiyun 	EC_FLASH_REGION_RW,
693*4882a593Smuzhiyun 	/*
694*4882a593Smuzhiyun 	 * Region which should be write-protected in the factory (a superset of
695*4882a593Smuzhiyun 	 * EC_FLASH_REGION_RO)
696*4882a593Smuzhiyun 	 */
697*4882a593Smuzhiyun 	EC_FLASH_REGION_WP_RO,
698*4882a593Smuzhiyun 	/* Number of regions */
699*4882a593Smuzhiyun 	EC_FLASH_REGION_COUNT,
700*4882a593Smuzhiyun };
701*4882a593Smuzhiyun 
702*4882a593Smuzhiyun struct ec_params_flash_region_info {
703*4882a593Smuzhiyun 	uint32_t region;  /* enum ec_flash_region */
704*4882a593Smuzhiyun } __packed;
705*4882a593Smuzhiyun 
706*4882a593Smuzhiyun struct ec_response_flash_region_info {
707*4882a593Smuzhiyun 	uint32_t offset;
708*4882a593Smuzhiyun 	uint32_t size;
709*4882a593Smuzhiyun } __packed;
710*4882a593Smuzhiyun 
711*4882a593Smuzhiyun /* Read/write VbNvContext */
712*4882a593Smuzhiyun #define EC_CMD_VBNV_CONTEXT 0x17
713*4882a593Smuzhiyun #define EC_VER_VBNV_CONTEXT 1
714*4882a593Smuzhiyun #define EC_VBNV_BLOCK_SIZE 16
715*4882a593Smuzhiyun 
716*4882a593Smuzhiyun enum ec_vbnvcontext_op {
717*4882a593Smuzhiyun 	EC_VBNV_CONTEXT_OP_READ,
718*4882a593Smuzhiyun 	EC_VBNV_CONTEXT_OP_WRITE,
719*4882a593Smuzhiyun };
720*4882a593Smuzhiyun 
721*4882a593Smuzhiyun struct ec_params_vbnvcontext {
722*4882a593Smuzhiyun 	uint32_t op;
723*4882a593Smuzhiyun 	uint8_t block[EC_VBNV_BLOCK_SIZE];
724*4882a593Smuzhiyun } __packed;
725*4882a593Smuzhiyun 
726*4882a593Smuzhiyun struct ec_response_vbnvcontext {
727*4882a593Smuzhiyun 	uint8_t block[EC_VBNV_BLOCK_SIZE];
728*4882a593Smuzhiyun } __packed;
729*4882a593Smuzhiyun 
730*4882a593Smuzhiyun /*****************************************************************************/
731*4882a593Smuzhiyun /* PWM commands */
732*4882a593Smuzhiyun 
733*4882a593Smuzhiyun /* Get fan target RPM */
734*4882a593Smuzhiyun #define EC_CMD_PWM_GET_FAN_TARGET_RPM 0x20
735*4882a593Smuzhiyun 
736*4882a593Smuzhiyun struct ec_response_pwm_get_fan_rpm {
737*4882a593Smuzhiyun 	uint32_t rpm;
738*4882a593Smuzhiyun } __packed;
739*4882a593Smuzhiyun 
740*4882a593Smuzhiyun /* Set target fan RPM */
741*4882a593Smuzhiyun #define EC_CMD_PWM_SET_FAN_TARGET_RPM 0x21
742*4882a593Smuzhiyun 
743*4882a593Smuzhiyun struct ec_params_pwm_set_fan_target_rpm {
744*4882a593Smuzhiyun 	uint32_t rpm;
745*4882a593Smuzhiyun } __packed;
746*4882a593Smuzhiyun 
747*4882a593Smuzhiyun /* Get keyboard backlight */
748*4882a593Smuzhiyun #define EC_CMD_PWM_GET_KEYBOARD_BACKLIGHT 0x22
749*4882a593Smuzhiyun 
750*4882a593Smuzhiyun struct ec_response_pwm_get_keyboard_backlight {
751*4882a593Smuzhiyun 	uint8_t percent;
752*4882a593Smuzhiyun 	uint8_t enabled;
753*4882a593Smuzhiyun } __packed;
754*4882a593Smuzhiyun 
755*4882a593Smuzhiyun /* Set keyboard backlight */
756*4882a593Smuzhiyun #define EC_CMD_PWM_SET_KEYBOARD_BACKLIGHT 0x23
757*4882a593Smuzhiyun 
758*4882a593Smuzhiyun struct ec_params_pwm_set_keyboard_backlight {
759*4882a593Smuzhiyun 	uint8_t percent;
760*4882a593Smuzhiyun } __packed;
761*4882a593Smuzhiyun 
762*4882a593Smuzhiyun /* Set target fan PWM duty cycle */
763*4882a593Smuzhiyun #define EC_CMD_PWM_SET_FAN_DUTY 0x24
764*4882a593Smuzhiyun 
765*4882a593Smuzhiyun struct ec_params_pwm_set_fan_duty {
766*4882a593Smuzhiyun 	uint32_t percent;
767*4882a593Smuzhiyun } __packed;
768*4882a593Smuzhiyun 
769*4882a593Smuzhiyun /*****************************************************************************/
770*4882a593Smuzhiyun /*
771*4882a593Smuzhiyun  * Lightbar commands. This looks worse than it is. Since we only use one HOST
772*4882a593Smuzhiyun  * command to say "talk to the lightbar", we put the "and tell it to do X" part
773*4882a593Smuzhiyun  * into a subcommand. We'll make separate structs for subcommands with
774*4882a593Smuzhiyun  * different input args, so that we know how much to expect.
775*4882a593Smuzhiyun  */
776*4882a593Smuzhiyun #define EC_CMD_LIGHTBAR_CMD 0x28
777*4882a593Smuzhiyun 
778*4882a593Smuzhiyun struct rgb_s {
779*4882a593Smuzhiyun 	uint8_t r, g, b;
780*4882a593Smuzhiyun };
781*4882a593Smuzhiyun 
782*4882a593Smuzhiyun #define LB_BATTERY_LEVELS 4
783*4882a593Smuzhiyun /* List of tweakable parameters. NOTE: It's __packed so it can be sent in a
784*4882a593Smuzhiyun  * host command, but the alignment is the same regardless. Keep it that way.
785*4882a593Smuzhiyun  */
786*4882a593Smuzhiyun struct lightbar_params {
787*4882a593Smuzhiyun 	/* Timing */
788*4882a593Smuzhiyun 	int google_ramp_up;
789*4882a593Smuzhiyun 	int google_ramp_down;
790*4882a593Smuzhiyun 	int s3s0_ramp_up;
791*4882a593Smuzhiyun 	int s0_tick_delay[2];			/* AC=0/1 */
792*4882a593Smuzhiyun 	int s0a_tick_delay[2];			/* AC=0/1 */
793*4882a593Smuzhiyun 	int s0s3_ramp_down;
794*4882a593Smuzhiyun 	int s3_sleep_for;
795*4882a593Smuzhiyun 	int s3_ramp_up;
796*4882a593Smuzhiyun 	int s3_ramp_down;
797*4882a593Smuzhiyun 
798*4882a593Smuzhiyun 	/* Oscillation */
799*4882a593Smuzhiyun 	uint8_t new_s0;
800*4882a593Smuzhiyun 	uint8_t osc_min[2];			/* AC=0/1 */
801*4882a593Smuzhiyun 	uint8_t osc_max[2];			/* AC=0/1 */
802*4882a593Smuzhiyun 	uint8_t w_ofs[2];			/* AC=0/1 */
803*4882a593Smuzhiyun 
804*4882a593Smuzhiyun 	/* Brightness limits based on the backlight and AC. */
805*4882a593Smuzhiyun 	uint8_t bright_bl_off_fixed[2];		/* AC=0/1 */
806*4882a593Smuzhiyun 	uint8_t bright_bl_on_min[2];		/* AC=0/1 */
807*4882a593Smuzhiyun 	uint8_t bright_bl_on_max[2];		/* AC=0/1 */
808*4882a593Smuzhiyun 
809*4882a593Smuzhiyun 	/* Battery level thresholds */
810*4882a593Smuzhiyun 	uint8_t battery_threshold[LB_BATTERY_LEVELS - 1];
811*4882a593Smuzhiyun 
812*4882a593Smuzhiyun 	/* Map [AC][battery_level] to color index */
813*4882a593Smuzhiyun 	uint8_t s0_idx[2][LB_BATTERY_LEVELS];	/* AP is running */
814*4882a593Smuzhiyun 	uint8_t s3_idx[2][LB_BATTERY_LEVELS];	/* AP is sleeping */
815*4882a593Smuzhiyun 
816*4882a593Smuzhiyun 	/* Color palette */
817*4882a593Smuzhiyun 	struct rgb_s color[8];			/* 0-3 are Google colors */
818*4882a593Smuzhiyun } __packed;
819*4882a593Smuzhiyun 
820*4882a593Smuzhiyun struct ec_params_lightbar {
821*4882a593Smuzhiyun 	uint8_t cmd;		      /* Command (see enum lightbar_command) */
822*4882a593Smuzhiyun 	union {
823*4882a593Smuzhiyun 		struct {
824*4882a593Smuzhiyun 			/* no args */
825*4882a593Smuzhiyun 		} dump, off, on, init, get_seq, get_params;
826*4882a593Smuzhiyun 
827*4882a593Smuzhiyun 		struct num {
828*4882a593Smuzhiyun 			uint8_t num;
829*4882a593Smuzhiyun 		} brightness, seq, demo;
830*4882a593Smuzhiyun 
831*4882a593Smuzhiyun 		struct reg {
832*4882a593Smuzhiyun 			uint8_t ctrl, reg, value;
833*4882a593Smuzhiyun 		} reg;
834*4882a593Smuzhiyun 
835*4882a593Smuzhiyun 		struct rgb {
836*4882a593Smuzhiyun 			uint8_t led, red, green, blue;
837*4882a593Smuzhiyun 		} rgb;
838*4882a593Smuzhiyun 
839*4882a593Smuzhiyun 		struct lightbar_params set_params;
840*4882a593Smuzhiyun 	};
841*4882a593Smuzhiyun } __packed;
842*4882a593Smuzhiyun 
843*4882a593Smuzhiyun struct ec_response_lightbar {
844*4882a593Smuzhiyun 	union {
845*4882a593Smuzhiyun 		struct dump {
846*4882a593Smuzhiyun 			struct {
847*4882a593Smuzhiyun 				uint8_t reg;
848*4882a593Smuzhiyun 				uint8_t ic0;
849*4882a593Smuzhiyun 				uint8_t ic1;
850*4882a593Smuzhiyun 			} vals[23];
851*4882a593Smuzhiyun 		} dump;
852*4882a593Smuzhiyun 
853*4882a593Smuzhiyun 		struct get_seq {
854*4882a593Smuzhiyun 			uint8_t num;
855*4882a593Smuzhiyun 		} get_seq;
856*4882a593Smuzhiyun 
857*4882a593Smuzhiyun 		struct lightbar_params get_params;
858*4882a593Smuzhiyun 
859*4882a593Smuzhiyun 		struct {
860*4882a593Smuzhiyun 			/* no return params */
861*4882a593Smuzhiyun 		} off, on, init, brightness, seq, reg, rgb, demo, set_params;
862*4882a593Smuzhiyun 	};
863*4882a593Smuzhiyun } __packed;
864*4882a593Smuzhiyun 
865*4882a593Smuzhiyun /* Lightbar commands */
866*4882a593Smuzhiyun enum lightbar_command {
867*4882a593Smuzhiyun 	LIGHTBAR_CMD_DUMP = 0,
868*4882a593Smuzhiyun 	LIGHTBAR_CMD_OFF = 1,
869*4882a593Smuzhiyun 	LIGHTBAR_CMD_ON = 2,
870*4882a593Smuzhiyun 	LIGHTBAR_CMD_INIT = 3,
871*4882a593Smuzhiyun 	LIGHTBAR_CMD_BRIGHTNESS = 4,
872*4882a593Smuzhiyun 	LIGHTBAR_CMD_SEQ = 5,
873*4882a593Smuzhiyun 	LIGHTBAR_CMD_REG = 6,
874*4882a593Smuzhiyun 	LIGHTBAR_CMD_RGB = 7,
875*4882a593Smuzhiyun 	LIGHTBAR_CMD_GET_SEQ = 8,
876*4882a593Smuzhiyun 	LIGHTBAR_CMD_DEMO = 9,
877*4882a593Smuzhiyun 	LIGHTBAR_CMD_GET_PARAMS = 10,
878*4882a593Smuzhiyun 	LIGHTBAR_CMD_SET_PARAMS = 11,
879*4882a593Smuzhiyun 	LIGHTBAR_NUM_CMDS
880*4882a593Smuzhiyun };
881*4882a593Smuzhiyun 
882*4882a593Smuzhiyun /*****************************************************************************/
883*4882a593Smuzhiyun /* LED control commands */
884*4882a593Smuzhiyun 
885*4882a593Smuzhiyun #define EC_CMD_LED_CONTROL 0x29
886*4882a593Smuzhiyun 
887*4882a593Smuzhiyun enum ec_led_id {
888*4882a593Smuzhiyun 	EC_LED_ID_BATTERY_LED = 0,
889*4882a593Smuzhiyun 	EC_LED_ID_POWER_BUTTON_LED,
890*4882a593Smuzhiyun 	EC_LED_ID_ADAPTER_LED,
891*4882a593Smuzhiyun };
892*4882a593Smuzhiyun 
893*4882a593Smuzhiyun /* LED control flags */
894*4882a593Smuzhiyun #define EC_LED_FLAGS_QUERY (1 << 0) /* Query LED capability only */
895*4882a593Smuzhiyun #define EC_LED_FLAGS_AUTO  (1 << 1) /* Switch LED back to automatic control */
896*4882a593Smuzhiyun 
897*4882a593Smuzhiyun enum ec_led_colors {
898*4882a593Smuzhiyun 	EC_LED_COLOR_RED = 0,
899*4882a593Smuzhiyun 	EC_LED_COLOR_GREEN,
900*4882a593Smuzhiyun 	EC_LED_COLOR_BLUE,
901*4882a593Smuzhiyun 	EC_LED_COLOR_YELLOW,
902*4882a593Smuzhiyun 	EC_LED_COLOR_WHITE,
903*4882a593Smuzhiyun 
904*4882a593Smuzhiyun 	EC_LED_COLOR_COUNT
905*4882a593Smuzhiyun };
906*4882a593Smuzhiyun 
907*4882a593Smuzhiyun struct ec_params_led_control {
908*4882a593Smuzhiyun 	uint8_t led_id;     /* Which LED to control */
909*4882a593Smuzhiyun 	uint8_t flags;      /* Control flags */
910*4882a593Smuzhiyun 
911*4882a593Smuzhiyun 	uint8_t brightness[EC_LED_COLOR_COUNT];
912*4882a593Smuzhiyun } __packed;
913*4882a593Smuzhiyun 
914*4882a593Smuzhiyun struct ec_response_led_control {
915*4882a593Smuzhiyun 	/*
916*4882a593Smuzhiyun 	 * Available brightness value range.
917*4882a593Smuzhiyun 	 *
918*4882a593Smuzhiyun 	 * Range 0 means color channel not present.
919*4882a593Smuzhiyun 	 * Range 1 means on/off control.
920*4882a593Smuzhiyun 	 * Other values means the LED is control by PWM.
921*4882a593Smuzhiyun 	 */
922*4882a593Smuzhiyun 	uint8_t brightness_range[EC_LED_COLOR_COUNT];
923*4882a593Smuzhiyun } __packed;
924*4882a593Smuzhiyun 
925*4882a593Smuzhiyun /*****************************************************************************/
926*4882a593Smuzhiyun /* Verified boot commands */
927*4882a593Smuzhiyun 
928*4882a593Smuzhiyun /*
929*4882a593Smuzhiyun  * Note: command code 0x29 version 0 was VBOOT_CMD in Link EVT; it may be
930*4882a593Smuzhiyun  * reused for other purposes with version > 0.
931*4882a593Smuzhiyun  */
932*4882a593Smuzhiyun 
933*4882a593Smuzhiyun /* Verified boot hash command */
934*4882a593Smuzhiyun #define EC_CMD_VBOOT_HASH 0x2A
935*4882a593Smuzhiyun 
936*4882a593Smuzhiyun struct ec_params_vboot_hash {
937*4882a593Smuzhiyun 	uint8_t cmd;             /* enum ec_vboot_hash_cmd */
938*4882a593Smuzhiyun 	uint8_t hash_type;       /* enum ec_vboot_hash_type */
939*4882a593Smuzhiyun 	uint8_t nonce_size;      /* Nonce size; may be 0 */
940*4882a593Smuzhiyun 	uint8_t reserved0;       /* Reserved; set 0 */
941*4882a593Smuzhiyun 	uint32_t offset;         /* Offset in flash to hash */
942*4882a593Smuzhiyun 	uint32_t size;           /* Number of bytes to hash */
943*4882a593Smuzhiyun 	uint8_t nonce_data[64];  /* Nonce data; ignored if nonce_size=0 */
944*4882a593Smuzhiyun } __packed;
945*4882a593Smuzhiyun 
946*4882a593Smuzhiyun struct ec_response_vboot_hash {
947*4882a593Smuzhiyun 	uint8_t status;          /* enum ec_vboot_hash_status */
948*4882a593Smuzhiyun 	uint8_t hash_type;       /* enum ec_vboot_hash_type */
949*4882a593Smuzhiyun 	uint8_t digest_size;     /* Size of hash digest in bytes */
950*4882a593Smuzhiyun 	uint8_t reserved0;       /* Ignore; will be 0 */
951*4882a593Smuzhiyun 	uint32_t offset;         /* Offset in flash which was hashed */
952*4882a593Smuzhiyun 	uint32_t size;           /* Number of bytes hashed */
953*4882a593Smuzhiyun 	uint8_t hash_digest[64]; /* Hash digest data */
954*4882a593Smuzhiyun } __packed;
955*4882a593Smuzhiyun 
956*4882a593Smuzhiyun enum ec_vboot_hash_cmd {
957*4882a593Smuzhiyun 	EC_VBOOT_HASH_GET = 0,       /* Get current hash status */
958*4882a593Smuzhiyun 	EC_VBOOT_HASH_ABORT = 1,     /* Abort calculating current hash */
959*4882a593Smuzhiyun 	EC_VBOOT_HASH_START = 2,     /* Start computing a new hash */
960*4882a593Smuzhiyun 	EC_VBOOT_HASH_RECALC = 3,    /* Synchronously compute a new hash */
961*4882a593Smuzhiyun };
962*4882a593Smuzhiyun 
963*4882a593Smuzhiyun enum ec_vboot_hash_type {
964*4882a593Smuzhiyun 	EC_VBOOT_HASH_TYPE_SHA256 = 0, /* SHA-256 */
965*4882a593Smuzhiyun };
966*4882a593Smuzhiyun 
967*4882a593Smuzhiyun enum ec_vboot_hash_status {
968*4882a593Smuzhiyun 	EC_VBOOT_HASH_STATUS_NONE = 0, /* No hash (not started, or aborted) */
969*4882a593Smuzhiyun 	EC_VBOOT_HASH_STATUS_DONE = 1, /* Finished computing a hash */
970*4882a593Smuzhiyun 	EC_VBOOT_HASH_STATUS_BUSY = 2, /* Busy computing a hash */
971*4882a593Smuzhiyun };
972*4882a593Smuzhiyun 
973*4882a593Smuzhiyun /*
974*4882a593Smuzhiyun  * Special values for offset for EC_VBOOT_HASH_START and EC_VBOOT_HASH_RECALC.
975*4882a593Smuzhiyun  * If one of these is specified, the EC will automatically update offset and
976*4882a593Smuzhiyun  * size to the correct values for the specified image (RO or RW).
977*4882a593Smuzhiyun  */
978*4882a593Smuzhiyun #define EC_VBOOT_HASH_OFFSET_RO 0xfffffffe
979*4882a593Smuzhiyun #define EC_VBOOT_HASH_OFFSET_RW 0xfffffffd
980*4882a593Smuzhiyun 
981*4882a593Smuzhiyun /*****************************************************************************/
982*4882a593Smuzhiyun /* USB charging control commands */
983*4882a593Smuzhiyun 
984*4882a593Smuzhiyun /* Set USB port charging mode */
985*4882a593Smuzhiyun #define EC_CMD_USB_CHARGE_SET_MODE 0x30
986*4882a593Smuzhiyun 
987*4882a593Smuzhiyun struct ec_params_usb_charge_set_mode {
988*4882a593Smuzhiyun 	uint8_t usb_port_id;
989*4882a593Smuzhiyun 	uint8_t mode;
990*4882a593Smuzhiyun } __packed;
991*4882a593Smuzhiyun 
992*4882a593Smuzhiyun /*****************************************************************************/
993*4882a593Smuzhiyun /* Persistent storage for host */
994*4882a593Smuzhiyun 
995*4882a593Smuzhiyun /* Maximum bytes that can be read/written in a single command */
996*4882a593Smuzhiyun #define EC_PSTORE_SIZE_MAX 64
997*4882a593Smuzhiyun 
998*4882a593Smuzhiyun /* Get persistent storage info */
999*4882a593Smuzhiyun #define EC_CMD_PSTORE_INFO 0x40
1000*4882a593Smuzhiyun 
1001*4882a593Smuzhiyun struct ec_response_pstore_info {
1002*4882a593Smuzhiyun 	/* Persistent storage size, in bytes */
1003*4882a593Smuzhiyun 	uint32_t pstore_size;
1004*4882a593Smuzhiyun 	/* Access size; read/write offset and size must be a multiple of this */
1005*4882a593Smuzhiyun 	uint32_t access_size;
1006*4882a593Smuzhiyun } __packed;
1007*4882a593Smuzhiyun 
1008*4882a593Smuzhiyun /*
1009*4882a593Smuzhiyun  * Read persistent storage
1010*4882a593Smuzhiyun  *
1011*4882a593Smuzhiyun  * Response is params.size bytes of data.
1012*4882a593Smuzhiyun  */
1013*4882a593Smuzhiyun #define EC_CMD_PSTORE_READ 0x41
1014*4882a593Smuzhiyun 
1015*4882a593Smuzhiyun struct ec_params_pstore_read {
1016*4882a593Smuzhiyun 	uint32_t offset;   /* Byte offset to read */
1017*4882a593Smuzhiyun 	uint32_t size;     /* Size to read in bytes */
1018*4882a593Smuzhiyun } __packed;
1019*4882a593Smuzhiyun 
1020*4882a593Smuzhiyun /* Write persistent storage */
1021*4882a593Smuzhiyun #define EC_CMD_PSTORE_WRITE 0x42
1022*4882a593Smuzhiyun 
1023*4882a593Smuzhiyun struct ec_params_pstore_write {
1024*4882a593Smuzhiyun 	uint32_t offset;   /* Byte offset to write */
1025*4882a593Smuzhiyun 	uint32_t size;     /* Size to write in bytes */
1026*4882a593Smuzhiyun 	uint8_t data[EC_PSTORE_SIZE_MAX];
1027*4882a593Smuzhiyun } __packed;
1028*4882a593Smuzhiyun 
1029*4882a593Smuzhiyun /*****************************************************************************/
1030*4882a593Smuzhiyun /* Real-time clock */
1031*4882a593Smuzhiyun 
1032*4882a593Smuzhiyun /* RTC params and response structures */
1033*4882a593Smuzhiyun struct ec_params_rtc {
1034*4882a593Smuzhiyun 	uint32_t time;
1035*4882a593Smuzhiyun } __packed;
1036*4882a593Smuzhiyun 
1037*4882a593Smuzhiyun struct ec_response_rtc {
1038*4882a593Smuzhiyun 	uint32_t time;
1039*4882a593Smuzhiyun } __packed;
1040*4882a593Smuzhiyun 
1041*4882a593Smuzhiyun /* These use ec_response_rtc */
1042*4882a593Smuzhiyun #define EC_CMD_RTC_GET_VALUE 0x44
1043*4882a593Smuzhiyun #define EC_CMD_RTC_GET_ALARM 0x45
1044*4882a593Smuzhiyun 
1045*4882a593Smuzhiyun /* These all use ec_params_rtc */
1046*4882a593Smuzhiyun #define EC_CMD_RTC_SET_VALUE 0x46
1047*4882a593Smuzhiyun #define EC_CMD_RTC_SET_ALARM 0x47
1048*4882a593Smuzhiyun 
1049*4882a593Smuzhiyun /*****************************************************************************/
1050*4882a593Smuzhiyun /* Port80 log access */
1051*4882a593Smuzhiyun 
1052*4882a593Smuzhiyun /* Get last port80 code from previous boot */
1053*4882a593Smuzhiyun #define EC_CMD_PORT80_LAST_BOOT 0x48
1054*4882a593Smuzhiyun 
1055*4882a593Smuzhiyun struct ec_response_port80_last_boot {
1056*4882a593Smuzhiyun 	uint16_t code;
1057*4882a593Smuzhiyun } __packed;
1058*4882a593Smuzhiyun 
1059*4882a593Smuzhiyun /*****************************************************************************/
1060*4882a593Smuzhiyun /* Thermal engine commands */
1061*4882a593Smuzhiyun 
1062*4882a593Smuzhiyun /* Set thershold value */
1063*4882a593Smuzhiyun #define EC_CMD_THERMAL_SET_THRESHOLD 0x50
1064*4882a593Smuzhiyun 
1065*4882a593Smuzhiyun struct ec_params_thermal_set_threshold {
1066*4882a593Smuzhiyun 	uint8_t sensor_type;
1067*4882a593Smuzhiyun 	uint8_t threshold_id;
1068*4882a593Smuzhiyun 	uint16_t value;
1069*4882a593Smuzhiyun } __packed;
1070*4882a593Smuzhiyun 
1071*4882a593Smuzhiyun /* Get threshold value */
1072*4882a593Smuzhiyun #define EC_CMD_THERMAL_GET_THRESHOLD 0x51
1073*4882a593Smuzhiyun 
1074*4882a593Smuzhiyun struct ec_params_thermal_get_threshold {
1075*4882a593Smuzhiyun 	uint8_t sensor_type;
1076*4882a593Smuzhiyun 	uint8_t threshold_id;
1077*4882a593Smuzhiyun } __packed;
1078*4882a593Smuzhiyun 
1079*4882a593Smuzhiyun struct ec_response_thermal_get_threshold {
1080*4882a593Smuzhiyun 	uint16_t value;
1081*4882a593Smuzhiyun } __packed;
1082*4882a593Smuzhiyun 
1083*4882a593Smuzhiyun /* Toggle automatic fan control */
1084*4882a593Smuzhiyun #define EC_CMD_THERMAL_AUTO_FAN_CTRL 0x52
1085*4882a593Smuzhiyun 
1086*4882a593Smuzhiyun /* Get TMP006 calibration data */
1087*4882a593Smuzhiyun #define EC_CMD_TMP006_GET_CALIBRATION 0x53
1088*4882a593Smuzhiyun 
1089*4882a593Smuzhiyun struct ec_params_tmp006_get_calibration {
1090*4882a593Smuzhiyun 	uint8_t index;
1091*4882a593Smuzhiyun } __packed;
1092*4882a593Smuzhiyun 
1093*4882a593Smuzhiyun struct ec_response_tmp006_get_calibration {
1094*4882a593Smuzhiyun 	float s0;
1095*4882a593Smuzhiyun 	float b0;
1096*4882a593Smuzhiyun 	float b1;
1097*4882a593Smuzhiyun 	float b2;
1098*4882a593Smuzhiyun } __packed;
1099*4882a593Smuzhiyun 
1100*4882a593Smuzhiyun /* Set TMP006 calibration data */
1101*4882a593Smuzhiyun #define EC_CMD_TMP006_SET_CALIBRATION 0x54
1102*4882a593Smuzhiyun 
1103*4882a593Smuzhiyun struct ec_params_tmp006_set_calibration {
1104*4882a593Smuzhiyun 	uint8_t index;
1105*4882a593Smuzhiyun 	uint8_t reserved[3];  /* Reserved; set 0 */
1106*4882a593Smuzhiyun 	float s0;
1107*4882a593Smuzhiyun 	float b0;
1108*4882a593Smuzhiyun 	float b1;
1109*4882a593Smuzhiyun 	float b2;
1110*4882a593Smuzhiyun } __packed;
1111*4882a593Smuzhiyun 
1112*4882a593Smuzhiyun /*****************************************************************************/
1113*4882a593Smuzhiyun /* MKBP - Matrix KeyBoard Protocol */
1114*4882a593Smuzhiyun 
1115*4882a593Smuzhiyun /*
1116*4882a593Smuzhiyun  * Read key state
1117*4882a593Smuzhiyun  *
1118*4882a593Smuzhiyun  * Returns raw data for keyboard cols; see ec_response_mkbp_info.cols for
1119*4882a593Smuzhiyun  * expected response size.
1120*4882a593Smuzhiyun  */
1121*4882a593Smuzhiyun #define EC_CMD_MKBP_STATE 0x60
1122*4882a593Smuzhiyun 
1123*4882a593Smuzhiyun /* Provide information about the matrix : number of rows and columns */
1124*4882a593Smuzhiyun #define EC_CMD_MKBP_INFO 0x61
1125*4882a593Smuzhiyun 
1126*4882a593Smuzhiyun struct ec_response_mkbp_info {
1127*4882a593Smuzhiyun 	uint32_t rows;
1128*4882a593Smuzhiyun 	uint32_t cols;
1129*4882a593Smuzhiyun 	uint8_t switches;
1130*4882a593Smuzhiyun } __packed;
1131*4882a593Smuzhiyun 
1132*4882a593Smuzhiyun /* Simulate key press */
1133*4882a593Smuzhiyun #define EC_CMD_MKBP_SIMULATE_KEY 0x62
1134*4882a593Smuzhiyun 
1135*4882a593Smuzhiyun struct ec_params_mkbp_simulate_key {
1136*4882a593Smuzhiyun 	uint8_t col;
1137*4882a593Smuzhiyun 	uint8_t row;
1138*4882a593Smuzhiyun 	uint8_t pressed;
1139*4882a593Smuzhiyun } __packed;
1140*4882a593Smuzhiyun 
1141*4882a593Smuzhiyun /* Configure keyboard scanning */
1142*4882a593Smuzhiyun #define EC_CMD_MKBP_SET_CONFIG 0x64
1143*4882a593Smuzhiyun #define EC_CMD_MKBP_GET_CONFIG 0x65
1144*4882a593Smuzhiyun 
1145*4882a593Smuzhiyun /* flags */
1146*4882a593Smuzhiyun enum mkbp_config_flags {
1147*4882a593Smuzhiyun 	EC_MKBP_FLAGS_ENABLE = 1,	/* Enable keyboard scanning */
1148*4882a593Smuzhiyun };
1149*4882a593Smuzhiyun 
1150*4882a593Smuzhiyun enum mkbp_config_valid {
1151*4882a593Smuzhiyun 	EC_MKBP_VALID_SCAN_PERIOD		= 1 << 0,
1152*4882a593Smuzhiyun 	EC_MKBP_VALID_POLL_TIMEOUT		= 1 << 1,
1153*4882a593Smuzhiyun 	EC_MKBP_VALID_MIN_POST_SCAN_DELAY	= 1 << 3,
1154*4882a593Smuzhiyun 	EC_MKBP_VALID_OUTPUT_SETTLE		= 1 << 4,
1155*4882a593Smuzhiyun 	EC_MKBP_VALID_DEBOUNCE_DOWN		= 1 << 5,
1156*4882a593Smuzhiyun 	EC_MKBP_VALID_DEBOUNCE_UP		= 1 << 6,
1157*4882a593Smuzhiyun 	EC_MKBP_VALID_FIFO_MAX_DEPTH		= 1 << 7,
1158*4882a593Smuzhiyun };
1159*4882a593Smuzhiyun 
1160*4882a593Smuzhiyun /* Configuration for our key scanning algorithm */
1161*4882a593Smuzhiyun struct ec_mkbp_config {
1162*4882a593Smuzhiyun 	uint32_t valid_mask;		/* valid fields */
1163*4882a593Smuzhiyun 	uint8_t flags;		/* some flags (enum mkbp_config_flags) */
1164*4882a593Smuzhiyun 	uint8_t valid_flags;		/* which flags are valid */
1165*4882a593Smuzhiyun 	uint16_t scan_period_us;	/* period between start of scans */
1166*4882a593Smuzhiyun 	/* revert to interrupt mode after no activity for this long */
1167*4882a593Smuzhiyun 	uint32_t poll_timeout_us;
1168*4882a593Smuzhiyun 	/*
1169*4882a593Smuzhiyun 	 * minimum post-scan relax time. Once we finish a scan we check
1170*4882a593Smuzhiyun 	 * the time until we are due to start the next one. If this time is
1171*4882a593Smuzhiyun 	 * shorter this field, we use this instead.
1172*4882a593Smuzhiyun 	 */
1173*4882a593Smuzhiyun 	uint16_t min_post_scan_delay_us;
1174*4882a593Smuzhiyun 	/* delay between setting up output and waiting for it to settle */
1175*4882a593Smuzhiyun 	uint16_t output_settle_us;
1176*4882a593Smuzhiyun 	uint16_t debounce_down_us;	/* time for debounce on key down */
1177*4882a593Smuzhiyun 	uint16_t debounce_up_us;	/* time for debounce on key up */
1178*4882a593Smuzhiyun 	/* maximum depth to allow for fifo (0 = no keyscan output) */
1179*4882a593Smuzhiyun 	uint8_t fifo_max_depth;
1180*4882a593Smuzhiyun } __packed;
1181*4882a593Smuzhiyun 
1182*4882a593Smuzhiyun struct ec_params_mkbp_set_config {
1183*4882a593Smuzhiyun 	struct ec_mkbp_config config;
1184*4882a593Smuzhiyun } __packed;
1185*4882a593Smuzhiyun 
1186*4882a593Smuzhiyun struct ec_response_mkbp_get_config {
1187*4882a593Smuzhiyun 	struct ec_mkbp_config config;
1188*4882a593Smuzhiyun } __packed;
1189*4882a593Smuzhiyun 
1190*4882a593Smuzhiyun /* Run the key scan emulation */
1191*4882a593Smuzhiyun #define EC_CMD_KEYSCAN_SEQ_CTRL 0x66
1192*4882a593Smuzhiyun 
1193*4882a593Smuzhiyun enum ec_keyscan_seq_cmd {
1194*4882a593Smuzhiyun 	EC_KEYSCAN_SEQ_STATUS = 0,	/* Get status information */
1195*4882a593Smuzhiyun 	EC_KEYSCAN_SEQ_CLEAR = 1,	/* Clear sequence */
1196*4882a593Smuzhiyun 	EC_KEYSCAN_SEQ_ADD = 2,		/* Add item to sequence */
1197*4882a593Smuzhiyun 	EC_KEYSCAN_SEQ_START = 3,	/* Start running sequence */
1198*4882a593Smuzhiyun 	EC_KEYSCAN_SEQ_COLLECT = 4,	/* Collect sequence summary data */
1199*4882a593Smuzhiyun };
1200*4882a593Smuzhiyun 
1201*4882a593Smuzhiyun enum ec_collect_flags {
1202*4882a593Smuzhiyun 	/*
1203*4882a593Smuzhiyun 	 * Indicates this scan was processed by the EC. Due to timing, some
1204*4882a593Smuzhiyun 	 * scans may be skipped.
1205*4882a593Smuzhiyun 	 */
1206*4882a593Smuzhiyun 	EC_KEYSCAN_SEQ_FLAG_DONE	= 1 << 0,
1207*4882a593Smuzhiyun };
1208*4882a593Smuzhiyun 
1209*4882a593Smuzhiyun struct ec_collect_item {
1210*4882a593Smuzhiyun 	uint8_t flags;		/* some flags (enum ec_collect_flags) */
1211*4882a593Smuzhiyun };
1212*4882a593Smuzhiyun 
1213*4882a593Smuzhiyun struct ec_params_keyscan_seq_ctrl {
1214*4882a593Smuzhiyun 	uint8_t cmd;	/* Command to send (enum ec_keyscan_seq_cmd) */
1215*4882a593Smuzhiyun 	union {
1216*4882a593Smuzhiyun 		struct {
1217*4882a593Smuzhiyun 			uint8_t active;		/* still active */
1218*4882a593Smuzhiyun 			uint8_t num_items;	/* number of items */
1219*4882a593Smuzhiyun 			/* Current item being presented */
1220*4882a593Smuzhiyun 			uint8_t cur_item;
1221*4882a593Smuzhiyun 		} status;
1222*4882a593Smuzhiyun 		struct {
1223*4882a593Smuzhiyun 			/*
1224*4882a593Smuzhiyun 			 * Absolute time for this scan, measured from the
1225*4882a593Smuzhiyun 			 * start of the sequence.
1226*4882a593Smuzhiyun 			 */
1227*4882a593Smuzhiyun 			uint32_t time_us;
1228*4882a593Smuzhiyun 			uint8_t scan[0];	/* keyscan data */
1229*4882a593Smuzhiyun 		} add;
1230*4882a593Smuzhiyun 		struct {
1231*4882a593Smuzhiyun 			uint8_t start_item;	/* First item to return */
1232*4882a593Smuzhiyun 			uint8_t num_items;	/* Number of items to return */
1233*4882a593Smuzhiyun 		} collect;
1234*4882a593Smuzhiyun 	};
1235*4882a593Smuzhiyun } __packed;
1236*4882a593Smuzhiyun 
1237*4882a593Smuzhiyun struct ec_result_keyscan_seq_ctrl {
1238*4882a593Smuzhiyun 	union {
1239*4882a593Smuzhiyun 		struct {
1240*4882a593Smuzhiyun 			uint8_t num_items;	/* Number of items */
1241*4882a593Smuzhiyun 			/* Data for each item */
1242*4882a593Smuzhiyun 			struct ec_collect_item item[0];
1243*4882a593Smuzhiyun 		} collect;
1244*4882a593Smuzhiyun 	};
1245*4882a593Smuzhiyun } __packed;
1246*4882a593Smuzhiyun 
1247*4882a593Smuzhiyun /*****************************************************************************/
1248*4882a593Smuzhiyun /* Temperature sensor commands */
1249*4882a593Smuzhiyun 
1250*4882a593Smuzhiyun /* Read temperature sensor info */
1251*4882a593Smuzhiyun #define EC_CMD_TEMP_SENSOR_GET_INFO 0x70
1252*4882a593Smuzhiyun 
1253*4882a593Smuzhiyun struct ec_params_temp_sensor_get_info {
1254*4882a593Smuzhiyun 	uint8_t id;
1255*4882a593Smuzhiyun } __packed;
1256*4882a593Smuzhiyun 
1257*4882a593Smuzhiyun struct ec_response_temp_sensor_get_info {
1258*4882a593Smuzhiyun 	char sensor_name[32];
1259*4882a593Smuzhiyun 	uint8_t sensor_type;
1260*4882a593Smuzhiyun } __packed;
1261*4882a593Smuzhiyun 
1262*4882a593Smuzhiyun /*****************************************************************************/
1263*4882a593Smuzhiyun 
1264*4882a593Smuzhiyun /*
1265*4882a593Smuzhiyun  * Note: host commands 0x80 - 0x87 are reserved to avoid conflict with ACPI
1266*4882a593Smuzhiyun  * commands accidentally sent to the wrong interface.  See the ACPI section
1267*4882a593Smuzhiyun  * below.
1268*4882a593Smuzhiyun  */
1269*4882a593Smuzhiyun 
1270*4882a593Smuzhiyun /*****************************************************************************/
1271*4882a593Smuzhiyun /* Host event commands */
1272*4882a593Smuzhiyun 
1273*4882a593Smuzhiyun /*
1274*4882a593Smuzhiyun  * Host event mask params and response structures, shared by all of the host
1275*4882a593Smuzhiyun  * event commands below.
1276*4882a593Smuzhiyun  */
1277*4882a593Smuzhiyun struct ec_params_host_event_mask {
1278*4882a593Smuzhiyun 	uint32_t mask;
1279*4882a593Smuzhiyun } __packed;
1280*4882a593Smuzhiyun 
1281*4882a593Smuzhiyun struct ec_response_host_event_mask {
1282*4882a593Smuzhiyun 	uint32_t mask;
1283*4882a593Smuzhiyun } __packed;
1284*4882a593Smuzhiyun 
1285*4882a593Smuzhiyun /* These all use ec_response_host_event_mask */
1286*4882a593Smuzhiyun #define EC_CMD_HOST_EVENT_GET_B         0x87
1287*4882a593Smuzhiyun #define EC_CMD_HOST_EVENT_GET_SMI_MASK  0x88
1288*4882a593Smuzhiyun #define EC_CMD_HOST_EVENT_GET_SCI_MASK  0x89
1289*4882a593Smuzhiyun #define EC_CMD_HOST_EVENT_GET_WAKE_MASK 0x8d
1290*4882a593Smuzhiyun 
1291*4882a593Smuzhiyun /* These all use ec_params_host_event_mask */
1292*4882a593Smuzhiyun #define EC_CMD_HOST_EVENT_SET_SMI_MASK  0x8a
1293*4882a593Smuzhiyun #define EC_CMD_HOST_EVENT_SET_SCI_MASK  0x8b
1294*4882a593Smuzhiyun #define EC_CMD_HOST_EVENT_CLEAR         0x8c
1295*4882a593Smuzhiyun #define EC_CMD_HOST_EVENT_SET_WAKE_MASK 0x8e
1296*4882a593Smuzhiyun #define EC_CMD_HOST_EVENT_CLEAR_B       0x8f
1297*4882a593Smuzhiyun 
1298*4882a593Smuzhiyun /*****************************************************************************/
1299*4882a593Smuzhiyun /* Switch commands */
1300*4882a593Smuzhiyun 
1301*4882a593Smuzhiyun /* Enable/disable LCD backlight */
1302*4882a593Smuzhiyun #define EC_CMD_SWITCH_ENABLE_BKLIGHT 0x90
1303*4882a593Smuzhiyun 
1304*4882a593Smuzhiyun struct ec_params_switch_enable_backlight {
1305*4882a593Smuzhiyun 	uint8_t enabled;
1306*4882a593Smuzhiyun } __packed;
1307*4882a593Smuzhiyun 
1308*4882a593Smuzhiyun /* Enable/disable WLAN/Bluetooth */
1309*4882a593Smuzhiyun #define EC_CMD_SWITCH_ENABLE_WIRELESS 0x91
1310*4882a593Smuzhiyun 
1311*4882a593Smuzhiyun struct ec_params_switch_enable_wireless {
1312*4882a593Smuzhiyun 	uint8_t enabled;
1313*4882a593Smuzhiyun } __packed;
1314*4882a593Smuzhiyun 
1315*4882a593Smuzhiyun /*****************************************************************************/
1316*4882a593Smuzhiyun /* GPIO commands. Only available on EC if write protect has been disabled. */
1317*4882a593Smuzhiyun 
1318*4882a593Smuzhiyun /* Set GPIO output value */
1319*4882a593Smuzhiyun #define EC_CMD_GPIO_SET 0x92
1320*4882a593Smuzhiyun 
1321*4882a593Smuzhiyun struct ec_params_gpio_set {
1322*4882a593Smuzhiyun 	char name[32];
1323*4882a593Smuzhiyun 	uint8_t val;
1324*4882a593Smuzhiyun } __packed;
1325*4882a593Smuzhiyun 
1326*4882a593Smuzhiyun /* Get GPIO value */
1327*4882a593Smuzhiyun #define EC_CMD_GPIO_GET 0x93
1328*4882a593Smuzhiyun 
1329*4882a593Smuzhiyun struct ec_params_gpio_get {
1330*4882a593Smuzhiyun 	char name[32];
1331*4882a593Smuzhiyun } __packed;
1332*4882a593Smuzhiyun struct ec_response_gpio_get {
1333*4882a593Smuzhiyun 	uint8_t val;
1334*4882a593Smuzhiyun } __packed;
1335*4882a593Smuzhiyun 
1336*4882a593Smuzhiyun /*****************************************************************************/
1337*4882a593Smuzhiyun /* I2C commands. Only available when flash write protect is unlocked. */
1338*4882a593Smuzhiyun 
1339*4882a593Smuzhiyun /* Read I2C bus */
1340*4882a593Smuzhiyun #define EC_CMD_I2C_READ 0x94
1341*4882a593Smuzhiyun 
1342*4882a593Smuzhiyun struct ec_params_i2c_read {
1343*4882a593Smuzhiyun 	uint16_t addr; /* 8-bit address (7-bit shifted << 1) */
1344*4882a593Smuzhiyun 	uint8_t read_size; /* Either 8 or 16. */
1345*4882a593Smuzhiyun 	uint8_t port;
1346*4882a593Smuzhiyun 	uint8_t offset;
1347*4882a593Smuzhiyun } __packed;
1348*4882a593Smuzhiyun struct ec_response_i2c_read {
1349*4882a593Smuzhiyun 	uint16_t data;
1350*4882a593Smuzhiyun } __packed;
1351*4882a593Smuzhiyun 
1352*4882a593Smuzhiyun /* Write I2C bus */
1353*4882a593Smuzhiyun #define EC_CMD_I2C_WRITE 0x95
1354*4882a593Smuzhiyun 
1355*4882a593Smuzhiyun struct ec_params_i2c_write {
1356*4882a593Smuzhiyun 	uint16_t data;
1357*4882a593Smuzhiyun 	uint16_t addr; /* 8-bit address (7-bit shifted << 1) */
1358*4882a593Smuzhiyun 	uint8_t write_size; /* Either 8 or 16. */
1359*4882a593Smuzhiyun 	uint8_t port;
1360*4882a593Smuzhiyun 	uint8_t offset;
1361*4882a593Smuzhiyun } __packed;
1362*4882a593Smuzhiyun 
1363*4882a593Smuzhiyun /*****************************************************************************/
1364*4882a593Smuzhiyun /* Charge state commands. Only available when flash write protect unlocked. */
1365*4882a593Smuzhiyun 
1366*4882a593Smuzhiyun /* Force charge state machine to stop in idle mode */
1367*4882a593Smuzhiyun #define EC_CMD_CHARGE_FORCE_IDLE 0x96
1368*4882a593Smuzhiyun 
1369*4882a593Smuzhiyun struct ec_params_force_idle {
1370*4882a593Smuzhiyun 	uint8_t enabled;
1371*4882a593Smuzhiyun } __packed;
1372*4882a593Smuzhiyun 
1373*4882a593Smuzhiyun /*****************************************************************************/
1374*4882a593Smuzhiyun /* Console commands. Only available when flash write protect is unlocked. */
1375*4882a593Smuzhiyun 
1376*4882a593Smuzhiyun /* Snapshot console output buffer for use by EC_CMD_CONSOLE_READ. */
1377*4882a593Smuzhiyun #define EC_CMD_CONSOLE_SNAPSHOT 0x97
1378*4882a593Smuzhiyun 
1379*4882a593Smuzhiyun /*
1380*4882a593Smuzhiyun  * Read next chunk of data from saved snapshot.
1381*4882a593Smuzhiyun  *
1382*4882a593Smuzhiyun  * Response is null-terminated string.  Empty string, if there is no more
1383*4882a593Smuzhiyun  * remaining output.
1384*4882a593Smuzhiyun  */
1385*4882a593Smuzhiyun #define EC_CMD_CONSOLE_READ 0x98
1386*4882a593Smuzhiyun 
1387*4882a593Smuzhiyun /*****************************************************************************/
1388*4882a593Smuzhiyun 
1389*4882a593Smuzhiyun /*
1390*4882a593Smuzhiyun  * Cut off battery power output if the battery supports.
1391*4882a593Smuzhiyun  *
1392*4882a593Smuzhiyun  * For unsupported battery, just don't implement this command and lets EC
1393*4882a593Smuzhiyun  * return EC_RES_INVALID_COMMAND.
1394*4882a593Smuzhiyun  */
1395*4882a593Smuzhiyun #define EC_CMD_BATTERY_CUT_OFF 0x99
1396*4882a593Smuzhiyun 
1397*4882a593Smuzhiyun /*****************************************************************************/
1398*4882a593Smuzhiyun /* USB port mux control. */
1399*4882a593Smuzhiyun 
1400*4882a593Smuzhiyun /*
1401*4882a593Smuzhiyun  * Switch USB mux or return to automatic switching.
1402*4882a593Smuzhiyun  */
1403*4882a593Smuzhiyun #define EC_CMD_USB_MUX 0x9a
1404*4882a593Smuzhiyun 
1405*4882a593Smuzhiyun struct ec_params_usb_mux {
1406*4882a593Smuzhiyun 	uint8_t mux;
1407*4882a593Smuzhiyun } __packed;
1408*4882a593Smuzhiyun 
1409*4882a593Smuzhiyun /*****************************************************************************/
1410*4882a593Smuzhiyun /* LDOs / FETs control. */
1411*4882a593Smuzhiyun 
1412*4882a593Smuzhiyun enum ec_ldo_state {
1413*4882a593Smuzhiyun 	EC_LDO_STATE_OFF = 0,	/* the LDO / FET is shut down */
1414*4882a593Smuzhiyun 	EC_LDO_STATE_ON = 1,	/* the LDO / FET is ON / providing power */
1415*4882a593Smuzhiyun };
1416*4882a593Smuzhiyun 
1417*4882a593Smuzhiyun /*
1418*4882a593Smuzhiyun  * Switch on/off a LDO.
1419*4882a593Smuzhiyun  */
1420*4882a593Smuzhiyun #define EC_CMD_LDO_SET 0x9b
1421*4882a593Smuzhiyun 
1422*4882a593Smuzhiyun struct ec_params_ldo_set {
1423*4882a593Smuzhiyun 	uint8_t index;
1424*4882a593Smuzhiyun 	uint8_t state;
1425*4882a593Smuzhiyun } __packed;
1426*4882a593Smuzhiyun 
1427*4882a593Smuzhiyun /*
1428*4882a593Smuzhiyun  * Get LDO state.
1429*4882a593Smuzhiyun  */
1430*4882a593Smuzhiyun #define EC_CMD_LDO_GET 0x9c
1431*4882a593Smuzhiyun 
1432*4882a593Smuzhiyun struct ec_params_ldo_get {
1433*4882a593Smuzhiyun 	uint8_t index;
1434*4882a593Smuzhiyun } __packed;
1435*4882a593Smuzhiyun 
1436*4882a593Smuzhiyun struct ec_response_ldo_get {
1437*4882a593Smuzhiyun 	uint8_t state;
1438*4882a593Smuzhiyun } __packed;
1439*4882a593Smuzhiyun 
1440*4882a593Smuzhiyun /*****************************************************************************/
1441*4882a593Smuzhiyun /* Power info. */
1442*4882a593Smuzhiyun 
1443*4882a593Smuzhiyun /*
1444*4882a593Smuzhiyun  * Get power info.
1445*4882a593Smuzhiyun  */
1446*4882a593Smuzhiyun #define EC_CMD_POWER_INFO 0x9d
1447*4882a593Smuzhiyun 
1448*4882a593Smuzhiyun struct ec_response_power_info {
1449*4882a593Smuzhiyun 	uint32_t usb_dev_type;
1450*4882a593Smuzhiyun 	uint16_t voltage_ac;
1451*4882a593Smuzhiyun 	uint16_t voltage_system;
1452*4882a593Smuzhiyun 	uint16_t current_system;
1453*4882a593Smuzhiyun 	uint16_t usb_current_limit;
1454*4882a593Smuzhiyun } __packed;
1455*4882a593Smuzhiyun 
1456*4882a593Smuzhiyun /*****************************************************************************/
1457*4882a593Smuzhiyun /* I2C passthru command */
1458*4882a593Smuzhiyun 
1459*4882a593Smuzhiyun #define EC_CMD_I2C_PASSTHRU 0x9e
1460*4882a593Smuzhiyun 
1461*4882a593Smuzhiyun /* Slave address is 10 (not 7) bit */
1462*4882a593Smuzhiyun #define EC_I2C_FLAG_10BIT	(1 << 16)
1463*4882a593Smuzhiyun 
1464*4882a593Smuzhiyun /* Read data; if not present, message is a write */
1465*4882a593Smuzhiyun #define EC_I2C_FLAG_READ	(1 << 15)
1466*4882a593Smuzhiyun 
1467*4882a593Smuzhiyun /* Mask for address */
1468*4882a593Smuzhiyun #define EC_I2C_ADDR_MASK	0x3ff
1469*4882a593Smuzhiyun 
1470*4882a593Smuzhiyun #define EC_I2C_STATUS_NAK	(1 << 0) /* Transfer was not acknowledged */
1471*4882a593Smuzhiyun #define EC_I2C_STATUS_TIMEOUT	(1 << 1) /* Timeout during transfer */
1472*4882a593Smuzhiyun 
1473*4882a593Smuzhiyun /* Any error */
1474*4882a593Smuzhiyun #define EC_I2C_STATUS_ERROR	(EC_I2C_STATUS_NAK | EC_I2C_STATUS_TIMEOUT)
1475*4882a593Smuzhiyun 
1476*4882a593Smuzhiyun struct ec_params_i2c_passthru_msg {
1477*4882a593Smuzhiyun 	uint16_t addr_flags;	/* I2C slave address (7 or 10 bits) and flags */
1478*4882a593Smuzhiyun 	uint16_t len;		/* Number of bytes to read or write */
1479*4882a593Smuzhiyun } __packed;
1480*4882a593Smuzhiyun 
1481*4882a593Smuzhiyun struct ec_params_i2c_passthru {
1482*4882a593Smuzhiyun 	uint8_t port;		/* I2C port number */
1483*4882a593Smuzhiyun 	uint8_t num_msgs;	/* Number of messages */
1484*4882a593Smuzhiyun 	struct ec_params_i2c_passthru_msg msg[];
1485*4882a593Smuzhiyun 	/* Data to write for all messages is concatenated here */
1486*4882a593Smuzhiyun } __packed;
1487*4882a593Smuzhiyun 
1488*4882a593Smuzhiyun struct ec_response_i2c_passthru {
1489*4882a593Smuzhiyun 	uint8_t i2c_status;	/* Status flags (EC_I2C_STATUS_...) */
1490*4882a593Smuzhiyun 	uint8_t num_msgs;	/* Number of messages processed */
1491*4882a593Smuzhiyun 	uint8_t data[];		/* Data read by messages concatenated here */
1492*4882a593Smuzhiyun } __packed;
1493*4882a593Smuzhiyun 
1494*4882a593Smuzhiyun 
1495*4882a593Smuzhiyun /*****************************************************************************/
1496*4882a593Smuzhiyun /* Temporary debug commands. TODO: remove this crosbug.com/p/13849 */
1497*4882a593Smuzhiyun 
1498*4882a593Smuzhiyun /*
1499*4882a593Smuzhiyun  * Dump charge state machine context.
1500*4882a593Smuzhiyun  *
1501*4882a593Smuzhiyun  * Response is a binary dump of charge state machine context.
1502*4882a593Smuzhiyun  */
1503*4882a593Smuzhiyun #define EC_CMD_CHARGE_DUMP 0xa0
1504*4882a593Smuzhiyun 
1505*4882a593Smuzhiyun /*
1506*4882a593Smuzhiyun  * Set maximum battery charging current.
1507*4882a593Smuzhiyun  */
1508*4882a593Smuzhiyun #define EC_CMD_CHARGE_CURRENT_LIMIT 0xa1
1509*4882a593Smuzhiyun 
1510*4882a593Smuzhiyun struct ec_params_current_limit {
1511*4882a593Smuzhiyun 	uint32_t limit; /* in mA */
1512*4882a593Smuzhiyun } __packed;
1513*4882a593Smuzhiyun 
1514*4882a593Smuzhiyun /*
1515*4882a593Smuzhiyun  * Set maximum external power current.
1516*4882a593Smuzhiyun  */
1517*4882a593Smuzhiyun #define EC_CMD_EXT_POWER_CURRENT_LIMIT 0xa2
1518*4882a593Smuzhiyun 
1519*4882a593Smuzhiyun struct ec_params_ext_power_current_limit {
1520*4882a593Smuzhiyun 	uint32_t limit; /* in mA */
1521*4882a593Smuzhiyun } __packed;
1522*4882a593Smuzhiyun 
1523*4882a593Smuzhiyun /*****************************************************************************/
1524*4882a593Smuzhiyun /* Smart battery pass-through */
1525*4882a593Smuzhiyun 
1526*4882a593Smuzhiyun /* Get / Set 16-bit smart battery registers */
1527*4882a593Smuzhiyun #define EC_CMD_SB_READ_WORD   0xb0
1528*4882a593Smuzhiyun #define EC_CMD_SB_WRITE_WORD  0xb1
1529*4882a593Smuzhiyun 
1530*4882a593Smuzhiyun /* Get / Set string smart battery parameters
1531*4882a593Smuzhiyun  * formatted as SMBUS "block".
1532*4882a593Smuzhiyun  */
1533*4882a593Smuzhiyun #define EC_CMD_SB_READ_BLOCK  0xb2
1534*4882a593Smuzhiyun #define EC_CMD_SB_WRITE_BLOCK 0xb3
1535*4882a593Smuzhiyun 
1536*4882a593Smuzhiyun struct ec_params_sb_rd {
1537*4882a593Smuzhiyun 	uint8_t reg;
1538*4882a593Smuzhiyun } __packed;
1539*4882a593Smuzhiyun 
1540*4882a593Smuzhiyun struct ec_response_sb_rd_word {
1541*4882a593Smuzhiyun 	uint16_t value;
1542*4882a593Smuzhiyun } __packed;
1543*4882a593Smuzhiyun 
1544*4882a593Smuzhiyun struct ec_params_sb_wr_word {
1545*4882a593Smuzhiyun 	uint8_t reg;
1546*4882a593Smuzhiyun 	uint16_t value;
1547*4882a593Smuzhiyun } __packed;
1548*4882a593Smuzhiyun 
1549*4882a593Smuzhiyun struct ec_response_sb_rd_block {
1550*4882a593Smuzhiyun 	uint8_t data[32];
1551*4882a593Smuzhiyun } __packed;
1552*4882a593Smuzhiyun 
1553*4882a593Smuzhiyun struct ec_params_sb_wr_block {
1554*4882a593Smuzhiyun 	uint8_t reg;
1555*4882a593Smuzhiyun 	uint16_t data[32];
1556*4882a593Smuzhiyun } __packed;
1557*4882a593Smuzhiyun 
1558*4882a593Smuzhiyun /*
1559*4882a593Smuzhiyun  * Entering Verified Boot Mode Command
1560*4882a593Smuzhiyun  * Default mode is VBOOT_MODE_NORMAL if EC did not receive this command.
1561*4882a593Smuzhiyun  * Valid Modes are: normal, developer, and recovery.
1562*4882a593Smuzhiyun  */
1563*4882a593Smuzhiyun #define EC_CMD_ENTERING_MODE 0xb6
1564*4882a593Smuzhiyun 
1565*4882a593Smuzhiyun struct ec_params_entering_mode {
1566*4882a593Smuzhiyun 	int vboot_mode;
1567*4882a593Smuzhiyun } __packed;
1568*4882a593Smuzhiyun 
1569*4882a593Smuzhiyun #define VBOOT_MODE_NORMAL    0
1570*4882a593Smuzhiyun #define VBOOT_MODE_DEVELOPER 1
1571*4882a593Smuzhiyun #define VBOOT_MODE_RECOVERY  2
1572*4882a593Smuzhiyun 
1573*4882a593Smuzhiyun /*****************************************************************************/
1574*4882a593Smuzhiyun /* System commands */
1575*4882a593Smuzhiyun 
1576*4882a593Smuzhiyun /*
1577*4882a593Smuzhiyun  * TODO: this is a confusing name, since it doesn't necessarily reboot the EC.
1578*4882a593Smuzhiyun  * Rename to "set image" or something similar.
1579*4882a593Smuzhiyun  */
1580*4882a593Smuzhiyun #define EC_CMD_REBOOT_EC 0xd2
1581*4882a593Smuzhiyun 
1582*4882a593Smuzhiyun /* Command */
1583*4882a593Smuzhiyun enum ec_reboot_cmd {
1584*4882a593Smuzhiyun 	EC_REBOOT_CANCEL = 0,        /* Cancel a pending reboot */
1585*4882a593Smuzhiyun 	EC_REBOOT_JUMP_RO = 1,       /* Jump to RO without rebooting */
1586*4882a593Smuzhiyun 	EC_REBOOT_JUMP_RW = 2,       /* Jump to RW without rebooting */
1587*4882a593Smuzhiyun 	/* (command 3 was jump to RW-B) */
1588*4882a593Smuzhiyun 	EC_REBOOT_COLD = 4,          /* Cold-reboot */
1589*4882a593Smuzhiyun 	EC_REBOOT_DISABLE_JUMP = 5,  /* Disable jump until next reboot */
1590*4882a593Smuzhiyun 	EC_REBOOT_HIBERNATE = 6      /* Hibernate EC */
1591*4882a593Smuzhiyun };
1592*4882a593Smuzhiyun 
1593*4882a593Smuzhiyun /* Flags for ec_params_reboot_ec.reboot_flags */
1594*4882a593Smuzhiyun #define EC_REBOOT_FLAG_RESERVED0      (1 << 0)  /* Was recovery request */
1595*4882a593Smuzhiyun #define EC_REBOOT_FLAG_ON_AP_SHUTDOWN (1 << 1)  /* Reboot after AP shutdown */
1596*4882a593Smuzhiyun 
1597*4882a593Smuzhiyun struct ec_params_reboot_ec {
1598*4882a593Smuzhiyun 	uint8_t cmd;           /* enum ec_reboot_cmd */
1599*4882a593Smuzhiyun 	uint8_t flags;         /* See EC_REBOOT_FLAG_* */
1600*4882a593Smuzhiyun } __packed;
1601*4882a593Smuzhiyun 
1602*4882a593Smuzhiyun /*
1603*4882a593Smuzhiyun  * Get information on last EC panic.
1604*4882a593Smuzhiyun  *
1605*4882a593Smuzhiyun  * Returns variable-length platform-dependent panic information.  See panic.h
1606*4882a593Smuzhiyun  * for details.
1607*4882a593Smuzhiyun  */
1608*4882a593Smuzhiyun #define EC_CMD_GET_PANIC_INFO 0xd3
1609*4882a593Smuzhiyun 
1610*4882a593Smuzhiyun /*****************************************************************************/
1611*4882a593Smuzhiyun /*
1612*4882a593Smuzhiyun  * ACPI commands
1613*4882a593Smuzhiyun  *
1614*4882a593Smuzhiyun  * These are valid ONLY on the ACPI command/data port.
1615*4882a593Smuzhiyun  */
1616*4882a593Smuzhiyun 
1617*4882a593Smuzhiyun /*
1618*4882a593Smuzhiyun  * ACPI Read Embedded Controller
1619*4882a593Smuzhiyun  *
1620*4882a593Smuzhiyun  * This reads from ACPI memory space on the EC (EC_ACPI_MEM_*).
1621*4882a593Smuzhiyun  *
1622*4882a593Smuzhiyun  * Use the following sequence:
1623*4882a593Smuzhiyun  *
1624*4882a593Smuzhiyun  *    - Write EC_CMD_ACPI_READ to EC_LPC_ADDR_ACPI_CMD
1625*4882a593Smuzhiyun  *    - Wait for EC_LPC_CMDR_PENDING bit to clear
1626*4882a593Smuzhiyun  *    - Write address to EC_LPC_ADDR_ACPI_DATA
1627*4882a593Smuzhiyun  *    - Wait for EC_LPC_CMDR_DATA bit to set
1628*4882a593Smuzhiyun  *    - Read value from EC_LPC_ADDR_ACPI_DATA
1629*4882a593Smuzhiyun  */
1630*4882a593Smuzhiyun #define EC_CMD_ACPI_READ 0x80
1631*4882a593Smuzhiyun 
1632*4882a593Smuzhiyun /*
1633*4882a593Smuzhiyun  * ACPI Write Embedded Controller
1634*4882a593Smuzhiyun  *
1635*4882a593Smuzhiyun  * This reads from ACPI memory space on the EC (EC_ACPI_MEM_*).
1636*4882a593Smuzhiyun  *
1637*4882a593Smuzhiyun  * Use the following sequence:
1638*4882a593Smuzhiyun  *
1639*4882a593Smuzhiyun  *    - Write EC_CMD_ACPI_WRITE to EC_LPC_ADDR_ACPI_CMD
1640*4882a593Smuzhiyun  *    - Wait for EC_LPC_CMDR_PENDING bit to clear
1641*4882a593Smuzhiyun  *    - Write address to EC_LPC_ADDR_ACPI_DATA
1642*4882a593Smuzhiyun  *    - Wait for EC_LPC_CMDR_PENDING bit to clear
1643*4882a593Smuzhiyun  *    - Write value to EC_LPC_ADDR_ACPI_DATA
1644*4882a593Smuzhiyun  */
1645*4882a593Smuzhiyun #define EC_CMD_ACPI_WRITE 0x81
1646*4882a593Smuzhiyun 
1647*4882a593Smuzhiyun /*
1648*4882a593Smuzhiyun  * ACPI Query Embedded Controller
1649*4882a593Smuzhiyun  *
1650*4882a593Smuzhiyun  * This clears the lowest-order bit in the currently pending host events, and
1651*4882a593Smuzhiyun  * sets the result code to the 1-based index of the bit (event 0x00000001 = 1,
1652*4882a593Smuzhiyun  * event 0x80000000 = 32), or 0 if no event was pending.
1653*4882a593Smuzhiyun  */
1654*4882a593Smuzhiyun #define EC_CMD_ACPI_QUERY_EVENT 0x84
1655*4882a593Smuzhiyun 
1656*4882a593Smuzhiyun /* Valid addresses in ACPI memory space, for read/write commands */
1657*4882a593Smuzhiyun /* Memory space version; set to EC_ACPI_MEM_VERSION_CURRENT */
1658*4882a593Smuzhiyun #define EC_ACPI_MEM_VERSION            0x00
1659*4882a593Smuzhiyun /*
1660*4882a593Smuzhiyun  * Test location; writing value here updates test compliment byte to (0xff -
1661*4882a593Smuzhiyun  * value).
1662*4882a593Smuzhiyun  */
1663*4882a593Smuzhiyun #define EC_ACPI_MEM_TEST               0x01
1664*4882a593Smuzhiyun /* Test compliment; writes here are ignored. */
1665*4882a593Smuzhiyun #define EC_ACPI_MEM_TEST_COMPLIMENT    0x02
1666*4882a593Smuzhiyun /* Keyboard backlight brightness percent (0 - 100) */
1667*4882a593Smuzhiyun #define EC_ACPI_MEM_KEYBOARD_BACKLIGHT 0x03
1668*4882a593Smuzhiyun 
1669*4882a593Smuzhiyun /* Current version of ACPI memory address space */
1670*4882a593Smuzhiyun #define EC_ACPI_MEM_VERSION_CURRENT 1
1671*4882a593Smuzhiyun 
1672*4882a593Smuzhiyun 
1673*4882a593Smuzhiyun /*****************************************************************************/
1674*4882a593Smuzhiyun /*
1675*4882a593Smuzhiyun  * Special commands
1676*4882a593Smuzhiyun  *
1677*4882a593Smuzhiyun  * These do not follow the normal rules for commands.  See each command for
1678*4882a593Smuzhiyun  * details.
1679*4882a593Smuzhiyun  */
1680*4882a593Smuzhiyun 
1681*4882a593Smuzhiyun /*
1682*4882a593Smuzhiyun  * Reboot NOW
1683*4882a593Smuzhiyun  *
1684*4882a593Smuzhiyun  * This command will work even when the EC LPC interface is busy, because the
1685*4882a593Smuzhiyun  * reboot command is processed at interrupt level.  Note that when the EC
1686*4882a593Smuzhiyun  * reboots, the host will reboot too, so there is no response to this command.
1687*4882a593Smuzhiyun  *
1688*4882a593Smuzhiyun  * Use EC_CMD_REBOOT_EC to reboot the EC more politely.
1689*4882a593Smuzhiyun  */
1690*4882a593Smuzhiyun #define EC_CMD_REBOOT 0xd1  /* Think "die" */
1691*4882a593Smuzhiyun 
1692*4882a593Smuzhiyun /*
1693*4882a593Smuzhiyun  * Resend last response (not supported on LPC).
1694*4882a593Smuzhiyun  *
1695*4882a593Smuzhiyun  * Returns EC_RES_UNAVAILABLE if there is no response available - for example,
1696*4882a593Smuzhiyun  * there was no previous command, or the previous command's response was too
1697*4882a593Smuzhiyun  * big to save.
1698*4882a593Smuzhiyun  */
1699*4882a593Smuzhiyun #define EC_CMD_RESEND_RESPONSE 0xdb
1700*4882a593Smuzhiyun 
1701*4882a593Smuzhiyun /*
1702*4882a593Smuzhiyun  * This header byte on a command indicate version 0. Any header byte less
1703*4882a593Smuzhiyun  * than this means that we are talking to an old EC which doesn't support
1704*4882a593Smuzhiyun  * versioning. In that case, we assume version 0.
1705*4882a593Smuzhiyun  *
1706*4882a593Smuzhiyun  * Header bytes greater than this indicate a later version. For example,
1707*4882a593Smuzhiyun  * EC_CMD_VERSION0 + 1 means we are using version 1.
1708*4882a593Smuzhiyun  *
1709*4882a593Smuzhiyun  * The old EC interface must not use commands 0dc or higher.
1710*4882a593Smuzhiyun  */
1711*4882a593Smuzhiyun #define EC_CMD_VERSION0 0xdc
1712*4882a593Smuzhiyun 
1713*4882a593Smuzhiyun #endif  /* !__ACPI__ */
1714*4882a593Smuzhiyun 
1715*4882a593Smuzhiyun #endif  /* __CROS_EC_COMMANDS_H */
1716