2 * Copyright (c) 2009 Clemens Zeidler
3 * Copyright (c) 2003-2007 Nate Lawson
4 * Copyright (c) 2000 Michael Smith
5 * Copyright (c) 2000 BSDi
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #ifndef ACPI_EMBEDDED_CONTROLLER_H
30 #define ACPI_EMBEDDED_CONTROLLER_H
36 #include <condition_variable.h>
39 #include <KernelExport.h>
44 # include "accommon.h"
45 # include "acnamesp.h"
47 # include "ACPIPrivate.h"
51 // #define TRACE_EMBEDDED_CONTROLLER
52 #ifdef TRACE_EMBEDDED_CONTROLLER
53 # define TRACE(x...) dprintf("EC: " x)
58 #define ERROR(x...) dprintf("EC: " x)
61 typedef uint8 EC_COMMAND
;
63 #define EC_COMMAND_UNKNOWN ((EC_COMMAND) 0x00)
64 #define EC_COMMAND_READ ((EC_COMMAND) 0x80)
65 #define EC_COMMAND_WRITE ((EC_COMMAND) 0x81)
66 #define EC_COMMAND_BURST_ENABLE ((EC_COMMAND) 0x82)
67 #define EC_COMMAND_BURST_DISABLE ((EC_COMMAND) 0x83)
68 #define EC_COMMAND_QUERY ((EC_COMMAND) 0x84)
73 * The encoding of the EC status register is illustrated below.
74 * Note that a set bit (1) indicates the property is TRUE
75 * (e.g. if bit 0 is set then the output buffer is full).
80 * | | | | | | | +- Output Buffer Full?
81 * | | | | | | +--- Input Buffer Full?
82 * | | | | | +----- <reserved>
83 * | | | | +------- Data Register is Command Byte?
84 * | | | +--------- Burst Mode Enabled?
85 * | | +----------- SCI Event?
86 * | +------------- SMI Event?
87 * +--------------- <reserved>
91 typedef uint8 EC_STATUS
;
93 #define EC_FLAG_OUTPUT_BUFFER ((EC_STATUS) 0x01)
94 #define EC_FLAG_INPUT_BUFFER ((EC_STATUS) 0x02)
95 #define EC_FLAG_DATA_IS_CMD ((EC_STATUS) 0x08)
96 #define EC_FLAG_BURST_MODE ((EC_STATUS) 0x10)
102 typedef uint8 EC_EVENT
;
104 #define EC_EVENT_UNKNOWN ((EC_EVENT) 0x00)
105 #define EC_EVENT_OUTPUT_BUFFER_FULL ((EC_EVENT) 0x01)
106 #define EC_EVENT_INPUT_BUFFER_EMPTY ((EC_EVENT) 0x02)
107 #define EC_EVENT_SCI ((EC_EVENT) 0x20)
108 #define EC_EVENT_SMI ((EC_EVENT) 0x40)
110 /* Data byte returned after burst enable indicating it was successful. */
111 #define EC_BURST_ACK 0x90
115 * Register access primitives
117 #define EC_GET_DATA(sc) \
118 bus_space_read_1((sc)->ec_data_pci_address)
120 #define EC_SET_DATA(sc, v) \
121 bus_space_write_1((sc)->ec_data_pci_address, (v))
123 #define EC_GET_CSR(sc) \
124 bus_space_read_1((sc)->ec_csr_pci_address)
126 #define EC_SET_CSR(sc, v) \
127 bus_space_write_1((sc)->ec_csr_pci_address, (v))
129 #define ACPI_PKG_VALID(pkg, size) \
130 ((pkg) != NULL && (pkg)->object_type == ACPI_TYPE_PACKAGE && \
131 (pkg)->package.count >= (size))
137 struct acpi_ec_cookie
{
139 acpi_module_info
* ec_acpi_module
;
140 acpi_device_module_info
* ec_acpi
;
141 acpi_device ec_handle
;
143 acpi_handle ec_gpehandle
;
146 int ec_data_pci_address
;
147 int ec_csr_pci_address
;
155 ConditionVariable ec_condition_var
;
162 * I couldn't find it in the spec but other implementations also use a
163 * value of 1 ms for the time to acquire global lock.
165 #define EC_LOCK_TIMEOUT 1000
167 /* Default delay in microseconds between each run of the status polling loop. */
168 #define EC_POLL_DELAY 5
170 /* Total time in ms spent waiting for a response from EC. */
171 #define EC_TIMEOUT 750
173 #define EVENT_READY(event, status) \
174 (((event) == EC_EVENT_OUTPUT_BUFFER_FULL && \
175 ((status) & EC_FLAG_OUTPUT_BUFFER) != 0) || \
176 ((event) == EC_EVENT_INPUT_BUFFER_EMPTY && \
177 ((status) & EC_FLAG_INPUT_BUFFER) == 0))
181 static int ec_burst_mode
= 1;
182 static int ec_polled_mode
= 0;
184 static int ec_timeout
= EC_TIMEOUT
;
188 EcLock(struct acpi_ec_cookie
*sc
)
190 /* If _GLK is non-zero, acquire the global lock. */
191 status_t status
= B_OK
;
193 status
= sc
->ec_acpi_module
->acquire_global_lock(EC_LOCK_TIMEOUT
,
198 mutex_lock(&sc
->ec_lock
);
204 EcUnlock(struct acpi_ec_cookie
*sc
)
206 mutex_unlock(&sc
->ec_lock
);
208 sc
->ec_acpi_module
->release_global_lock(sc
->ec_glkhandle
);
212 static uint32
EcGpeHandler(acpi_handle gpeDevice
, uint32 gpeNumber
,
215 static acpi_status
EcSpaceSetup(acpi_handle region
, uint32 function
,
216 void *context
, void **return_Context
);
217 static acpi_status
EcSpaceHandler(uint32 function
,
218 acpi_physical_address address
,
219 uint32 width
, int *value
,
220 void *context
, void *regionContext
);
221 static acpi_status
EcWaitEvent(struct acpi_ec_cookie
*sc
, EC_EVENT event
,
223 static acpi_status
EcCommand(struct acpi_ec_cookie
*sc
, EC_COMMAND cmd
);
224 static acpi_status
EcRead(struct acpi_ec_cookie
*sc
, uint8 address
,
226 static acpi_status
EcWrite(struct acpi_ec_cookie
*sc
, uint8 address
,
230 #endif // ACPI_EMBEDDED_CONTROLLER_H