blob: 6b04f304ede0231e3256d68ce1fbf68dfe7a2dd0 [file] [log] [blame]
Nico Huber7bb02512013-05-23 16:35:05 +02001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2013 secunet Security Networks AG
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; version 2 of
9 * the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
Nico Huber7bb02512013-05-23 16:35:05 +020015 */
16
17/*
18 * ACPI style embedded controller commands
19 *
20 * Controlled by the following preprocessor defines:
21 * EC_SC_IO I/o address of the EC_SC register
22 * EC_DATA_IO I/o address of the EC_DATA register
23 */
24
25#define EC_MUTEX ECMX
26#define WAIT_EC_SC WECC
27#define SEND_EC_COMMAND SECC
28#define SEND_EC_DATA SECD
29#define RECV_EC_DATA RECD
30#define EC_READ ECRD
31#define EC_WRITE ECWR
32#define EC_SC ECSC
33#define EC_DATA ECDT
34
35#define EC_OBF 0x01 /* Output buffer full (EC_DATA) */
36#define EC_IBF 0x02 /* Input buffer full (EC_DATA or EC_SC) */
37
38#define EC_ERROR_MASK 0xff00
39#define EC_TIMEOUT 0x8000
40
41#define EC_READ_CMD 0x80
42#define EC_WRITE_CMD 0x81
43
44Mutex(EC_MUTEX, 1)
45
46OperationRegion(ERSC, SystemIO, EC_SC_IO, 1)
47Field(ERSC, ByteAcc, NoLock, Preserve) { EC_SC, 8 }
48OperationRegion(ERDT, SystemIO, EC_DATA_IO, 1)
49Field(ERDT, ByteAcc, NoLock, Preserve) { EC_DATA, 8 }
50
51/*
52 * Wait for a bit in the status and command (EC_SC) register
53 *
54 * The caller is responsible of acquiring the EC_MUTEX before
55 * calling this method.
56 *
57 * Arg0: Mask, Arg1: State waiting for
58 * Returns EC_TIMEOUT if timed out, 0 else
59 */
60Method (WAIT_EC_SC, 2)
61{
62 Store (0x7ff, Local0) /* Timeout */
63 While (LAnd (LNotEqual (And (EC_SC, Arg0), Arg1), Decrement (Local0))) {
64 Stall (10)
65 }
66 If (Local0) {
67 Return (0)
68 } Else {
69 Return (EC_TIMEOUT)
70 }
71}
72
73/*
74 * Send command byte in Arg0 to status and command (EC_SC) register
75 *
76 * The caller is responsible of acquiring the EC_MUTEX before
77 * calling this method.
78 *
79 * Returns EC_TIMEOUT if timed out, 0 else
80 */
81Method (SEND_EC_COMMAND, 1)
82{
83 Store (WAIT_EC_SC (EC_IBF, 0), Local0)
84 If (LNot (Local0)) {
85 Store (Arg0, EC_SC)
86 }
87 Return (Local0)
88}
89
90/*
91 * Send data byte in Arg0 to data (EC_DATA) register
92 *
93 * The caller is responsible of acquiring the EC_MUTEX before
94 * calling this method.
95 *
96 * Returns EC_TIMEOUT if timed out, 0 else
97 */
98Method (SEND_EC_DATA, 1)
99{
100 Store (WAIT_EC_SC (EC_IBF, 0), Local0)
101 If (LNot (Local0)) {
102 Store (Arg0, EC_DATA)
103 }
104 Return (Local0)
105}
106
107/*
108 * Read one byte of data from data (EC_DATA) register
109 *
110 * The caller is responsible of acquiring the EC_MUTEX before
111 * calling this method.
112 *
113 * Returns EC_TIMEOUT if timed out, the read data byte else
114 */
115Method (RECV_EC_DATA)
116{
117 Store (WAIT_EC_SC (EC_OBF, EC_OBF), Local0)
118 If (LNot (Local0)) {
119 Return (EC_DATA)
120 } Else {
121 Return (Local0)
122 }
123}
124
125/*
126 * Read one byte from ec memory (cmd 0x80)
127 *
128 * Arg0: Address (1 byte) to read from
129 * Returns EC_TIMEOUT if timed out, the read data byte else
130 */
131Method (EC_READ, 1)
132{
133 Acquire (EC_MUTEX, 0xffff)
134 Store (SEND_EC_COMMAND (EC_READ_CMD), Local0)
135 If (LNot (Local0)) {
136 Store (SEND_EC_DATA (Arg0), Local0)
137 }
138 If (LNot (Local0)) {
139 Store (RECV_EC_DATA (), Local0)
140 }
141 Release (EC_MUTEX)
142
143 Return (Local0)
144}
145
146/*
147 * Write one byte to ec memory (cmd 0x81)
148 *
149 * Arg0: Address (1 byte) to write to
150 * Arg1: Byte to write
151 * Returns EC_TIMEOUT if timed out, 0 else
152 */
153Method (EC_WRITE, 2)
154{
155 Acquire (EC_MUTEX, 0xffff)
156 Store (SEND_EC_COMMAND (EC_WRITE_CMD), Local0)
157 If (LNot (Local0)) {
158 Store (SEND_EC_DATA (Arg0), Local0)
159 }
160 If (LNot (Local0)) {
161 Store (SEND_EC_DATA (Arg1), Local0)
162 }
163 Release (EC_MUTEX)
164
165 Return (Local0)
166}