1/* SPDX-License-Identifier: GPL-2.0-only */ 2 3/* 4 * ACPI style embedded controller commands 5 * 6 * Controlled by the following preprocessor defines: 7 * EC_SC_IO I/o address of the EC_SC register 8 * EC_DATA_IO I/o address of the EC_DATA register 9 */ 10 11#define EC_MUTEX ECMX 12#define WAIT_EC_SC WECC 13#define SEND_EC_COMMAND SECC 14#define SEND_EC_DATA SECD 15#define RECV_EC_DATA RECD 16#define EC_READ ECRD 17#define EC_WRITE ECWR 18#define EC_SC ECSC 19#define EC_DATA ECDT 20 21#define EC_OBF 0x01 /* Output buffer full (EC_DATA) */ 22#define EC_IBF 0x02 /* Input buffer full (EC_DATA or EC_SC) */ 23 24#define EC_ERROR_MASK 0xff00 25#define EC_TIMEOUT 0x8000 26 27#define EC_READ_CMD 0x80 28#define EC_WRITE_CMD 0x81 29 30Mutex(EC_MUTEX, 1) 31 32OperationRegion(ERSC, SystemIO, EC_SC_IO, 1) 33Field(ERSC, ByteAcc, NoLock, Preserve) { EC_SC, 8 } 34OperationRegion(ERDT, SystemIO, EC_DATA_IO, 1) 35Field(ERDT, ByteAcc, NoLock, Preserve) { EC_DATA, 8 } 36 37/* 38 * Wait for a bit in the status and command (EC_SC) register 39 * 40 * The caller is responsible of acquiring the EC_MUTEX before 41 * calling this method. 42 * 43 * Arg0: Mask, Arg1: State waiting for 44 * Returns EC_TIMEOUT if timed out, 0 else 45 */ 46Method (WAIT_EC_SC, 2) 47{ 48 Local0 = 0x7ff /* Timeout */ 49 While (((EC_SC & Arg0) != Arg1) && Local0--) { 50 Stall (10) 51 } 52 If (Local0) { 53 Return (0) 54 } Else { 55 Return (EC_TIMEOUT) 56 } 57} 58 59/* 60 * Send command byte in Arg0 to status and command (EC_SC) register 61 * 62 * The caller is responsible of acquiring the EC_MUTEX before 63 * calling this method. 64 * 65 * Returns EC_TIMEOUT if timed out, 0 else 66 */ 67Method (SEND_EC_COMMAND, 1) 68{ 69 Local0 = WAIT_EC_SC (EC_IBF, 0) 70 If (!Local0) { 71 EC_SC = Arg0 72 } 73 Return (Local0) 74} 75 76/* 77 * Send data byte in Arg0 to data (EC_DATA) register 78 * 79 * The caller is responsible of acquiring the EC_MUTEX before 80 * calling this method. 81 * 82 * Returns EC_TIMEOUT if timed out, 0 else 83 */ 84Method (SEND_EC_DATA, 1) 85{ 86 Local0 = WAIT_EC_SC (EC_IBF, 0) 87 If (!Local0) { 88 EC_DATA = Arg0 89 } 90 Return (Local0) 91} 92 93/* 94 * Read one byte of data from data (EC_DATA) register 95 * 96 * The caller is responsible of acquiring the EC_MUTEX before 97 * calling this method. 98 * 99 * Returns EC_TIMEOUT if timed out, the read data byte else 100 */ 101Method (RECV_EC_DATA) 102{ 103 Local0 = WAIT_EC_SC (EC_OBF, EC_OBF) 104 If (!Local0) { 105 Return (EC_DATA) 106 } Else { 107 Return (Local0) 108 } 109} 110 111/* 112 * Read one byte from ec memory (cmd 0x80) 113 * 114 * Arg0: Address (1 byte) to read from 115 * Returns EC_TIMEOUT if timed out, the read data byte else 116 */ 117Method (EC_READ, 1) 118{ 119 Acquire (EC_MUTEX, 0xffff) 120 Local0 = SEND_EC_COMMAND (EC_READ_CMD) 121 If (!Local0) { 122 Local0 = SEND_EC_DATA (Arg0) 123 } 124 If (!Local0) { 125 Local0 = RECV_EC_DATA () 126 } 127 Release (EC_MUTEX) 128 129 Return (Local0) 130} 131 132/* 133 * Write one byte to ec memory (cmd 0x81) 134 * 135 * Arg0: Address (1 byte) to write to 136 * Arg1: Byte to write 137 * Returns EC_TIMEOUT if timed out, 0 else 138 */ 139Method (EC_WRITE, 2) 140{ 141 Acquire (EC_MUTEX, 0xffff) 142 Local0 = SEND_EC_COMMAND (EC_WRITE_CMD) 143 If (!Local0) { 144 Local0 = SEND_EC_DATA (Arg0) 145 } 146 If (!Local0) { 147 Local0 = SEND_EC_DATA (Arg1) 148 } 149 Release (EC_MUTEX) 150 151 Return (Local0) 152} 153