1 /*- 2 * Copyright (c) 2009 Clemens Zeidler 3 * Copyright (c) 2003-2007 Nate Lawson 4 * Copyright (c) 2000 Michael Smith 5 * Copyright (c) 2000 BSDi 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 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. 16 * 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 27 * SUCH DAMAGE. 28 */ 29 #ifndef ACPI_EMBEDDED_CONTROLLER_H 30 #define ACPI_EMBEDDED_CONTROLLER_H 31 32 33 #include <ctype.h> 34 35 #include <ACPI.h> 36 #include <condition_variable.h> 37 38 #include <Drivers.h> 39 #include <KernelExport.h> 40 #include <lock.h> 41 42 extern "C" { 43 # include "acpi.h" 44 # include "accommon.h" 45 # include "acnamesp.h" 46 # include "actypes.h" 47 # include "ACPIPrivate.h" 48 } 49 50 51 // #define TRACE_EMBEDDED_CONTROLLER 52 #ifdef TRACE_EMBEDDED_CONTROLLER 53 # define TRACE(x...) dprintf("EC: " x) 54 #else 55 # define TRACE(x...) 56 #endif 57 58 #define ERROR(x...) dprintf("EC: " x) 59 60 61 typedef uint8 EC_COMMAND; 62 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) 69 70 /* 71 * EC_STATUS: 72 * ---------- 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). 76 * +-+-+-+-+-+-+-+-+ 77 * |7|6|5|4|3|2|1|0| 78 * +-+-+-+-+-+-+-+-+ 79 * | | | | | | | | 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> 88 * 89 */ 90 91 typedef uint8 EC_STATUS; 92 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) 97 98 /* 99 * EC_EVENT: 100 * --------- 101 */ 102 typedef uint8 EC_EVENT; 103 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) 109 110 /* Data byte returned after burst enable indicating it was successful. */ 111 #define EC_BURST_ACK 0x90 112 113 114 /* 115 * Register access primitives 116 */ 117 #define EC_GET_DATA(sc) \ 118 bus_space_read_1((sc)->ec_data_pci_address) 119 120 #define EC_SET_DATA(sc, v) \ 121 bus_space_write_1((sc)->ec_data_pci_address, (v)) 122 123 #define EC_GET_CSR(sc) \ 124 bus_space_read_1((sc)->ec_csr_pci_address) 125 126 #define EC_SET_CSR(sc, v) \ 127 bus_space_write_1((sc)->ec_csr_pci_address, (v)) 128 129 #define ACPI_PKG_VALID(pkg, size) \ 130 ((pkg) != NULL && (pkg)->object_type == ACPI_TYPE_PACKAGE && \ 131 (pkg)->data.package.count >= (size)) 132 133 134 /* 135 * Driver cookie. 136 */ 137 struct acpi_ec_cookie { 138 device_node* ec_dev; 139 acpi_module_info* ec_acpi_module; 140 acpi_device_module_info* ec_acpi; 141 acpi_device ec_handle; 142 int ec_uid; 143 acpi_handle ec_gpehandle; 144 uint8 ec_gpebit; 145 146 int ec_data_pci_address; 147 int ec_csr_pci_address; 148 149 int ec_glk; 150 uint32 ec_glkhandle; 151 mutex ec_lock; 152 int ec_burstactive; 153 int ec_sci_pending; 154 vint32 ec_gencount; 155 ConditionVariable ec_condition_var; 156 int ec_suspending; 157 }; 158 159 160 /* 161 * XXX njl 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. 164 */ 165 #define EC_LOCK_TIMEOUT 1000 166 167 /* Default delay in microseconds between each run of the status polling loop. */ 168 #define EC_POLL_DELAY 5 169 170 /* Total time in ms spent waiting for a response from EC. */ 171 #define EC_TIMEOUT 750 172 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)) 178 179 180 181 static int ec_burst_mode = 1; 182 static int ec_polled_mode = 0; 183 184 static int ec_timeout = EC_TIMEOUT; 185 186 187 static status_t 188 EcLock(struct acpi_ec_cookie *sc) 189 { 190 /* If _GLK is non-zero, acquire the global lock. */ 191 status_t status = B_OK; 192 if (sc->ec_glk) { 193 status = sc->ec_acpi_module->acquire_global_lock(EC_LOCK_TIMEOUT, 194 &sc->ec_glkhandle); 195 if (status != B_OK) 196 return status; 197 } 198 mutex_lock(&sc->ec_lock); 199 return status; 200 } 201 202 203 static void 204 EcUnlock(struct acpi_ec_cookie *sc) 205 { 206 mutex_unlock(&sc->ec_lock); 207 if (sc->ec_glk) 208 sc->ec_acpi_module->release_global_lock(sc->ec_glkhandle); 209 } 210 211 212 static uint32 EcGpeHandler(acpi_handle gpeDevice, uint32 gpeNumber, 213 void *context); 214 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, 222 int32 gen_count); 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, 225 uint8 *readData); 226 static acpi_status EcWrite(struct acpi_ec_cookie *sc, uint8 address, 227 uint8 writeData); 228 229 230 #endif // ACPI_EMBEDDED_CONTROLLER_H 231