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