#ifndef ACPI_EMBEDDED_CONTROLLER_H
#define ACPI_EMBEDDED_CONTROLLER_H
#include <ctype.h>
#include <ACPI.h>
#include <condition_variable.h>
#include <Drivers.h>
#include <KernelExport.h>
#include <lock.h>
extern "C" {
# include "acpi.h"
# include "accommon.h"
# include "acnamesp.h"
# include "actypes.h"
# include "ACPIPrivate.h"
}
#ifdef TRACE_EMBEDDED_CONTROLLER
# define TRACE(x...) dprintf("EC: " x)
#else
# define TRACE(x...)
#endif
#define ERROR(x...) dprintf("EC: " x)
typedef uint8 EC_COMMAND;
#define EC_COMMAND_UNKNOWN ((EC_COMMAND) 0x00)
#define EC_COMMAND_READ ((EC_COMMAND) 0x80)
#define EC_COMMAND_WRITE ((EC_COMMAND) 0x81)
#define EC_COMMAND_BURST_ENABLE ((EC_COMMAND) 0x82)
#define EC_COMMAND_BURST_DISABLE ((EC_COMMAND) 0x83)
#define EC_COMMAND_QUERY ((EC_COMMAND) 0x84)
typedef uint8 EC_STATUS;
#define EC_FLAG_OUTPUT_BUFFER ((EC_STATUS) 0x01)
#define EC_FLAG_INPUT_BUFFER ((EC_STATUS) 0x02)
#define EC_FLAG_DATA_IS_CMD ((EC_STATUS) 0x08)
#define EC_FLAG_BURST_MODE ((EC_STATUS) 0x10)
typedef uint8 EC_EVENT;
#define EC_EVENT_UNKNOWN ((EC_EVENT) 0x00)
#define EC_EVENT_OUTPUT_BUFFER_FULL ((EC_EVENT) 0x01)
#define EC_EVENT_INPUT_BUFFER_EMPTY ((EC_EVENT) 0x02)
#define EC_EVENT_SCI ((EC_EVENT) 0x20)
#define EC_EVENT_SMI ((EC_EVENT) 0x40)
#define EC_BURST_ACK 0x90
#define EC_GET_DATA(sc) \
bus_space_read_1((sc)->ec_data_pci_address)
#define EC_SET_DATA(sc, v) \
bus_space_write_1((sc)->ec_data_pci_address, (v))
#define EC_GET_CSR(sc) \
bus_space_read_1((sc)->ec_csr_pci_address)
#define EC_SET_CSR(sc, v) \
bus_space_write_1((sc)->ec_csr_pci_address, (v))
#define ACPI_PKG_VALID(pkg, size) \
((pkg) != NULL && (pkg)->object_type == ACPI_TYPE_PACKAGE && \
(pkg)->package.count >= (size))
struct acpi_ec_cookie {
device_node* ec_dev;
acpi_module_info* ec_acpi_module;
acpi_device_module_info* ec_acpi;
acpi_device ec_handle;
int ec_uid;
acpi_handle ec_gpehandle;
uint8 ec_gpebit;
int ec_data_pci_address;
int ec_csr_pci_address;
int ec_glk;
uint32 ec_glkhandle;
mutex ec_lock;
int ec_burstactive;
int32 ec_sci_pending;
int32 ec_gencount;
ConditionVariable ec_condition_var;
int ec_suspending;
};
#define EC_LOCK_TIMEOUT 1000
#define EC_POLL_DELAY 50
#define EC_TIMEOUT 750
#define EVENT_READY(event, status) \
(((event) == EC_EVENT_OUTPUT_BUFFER_FULL && \
((status) & EC_FLAG_OUTPUT_BUFFER) != 0) || \
((event) == EC_EVENT_INPUT_BUFFER_EMPTY && \
((status) & EC_FLAG_INPUT_BUFFER) == 0))
static bool ec_burst_mode = true;
static bool ec_polled_mode = false;
static int ec_timeout = EC_TIMEOUT;
static status_t
EcLock(struct acpi_ec_cookie *sc)
{
if (sc->ec_glk) {
status_t status = sc->ec_acpi_module->acquire_global_lock(EC_LOCK_TIMEOUT,
&sc->ec_glkhandle);
if (status != B_OK)
return status;
}
return mutex_lock(&sc->ec_lock);
}
static void
EcUnlock(struct acpi_ec_cookie *sc)
{
mutex_unlock(&sc->ec_lock);
if (sc->ec_glk)
sc->ec_acpi_module->release_global_lock(sc->ec_glkhandle);
}
static uint32 EcGpeHandler(acpi_handle gpeDevice, uint32 gpeNumber,
void *context);
static acpi_status EcSpaceSetup(acpi_handle region, uint32 function,
void *context, void **return_Context);
static acpi_status EcSpaceHandler(uint32 function,
acpi_physical_address address,
uint32 width, int *value,
void *context, void *regionContext);
static acpi_status EcWaitEvent(struct acpi_ec_cookie *sc, EC_EVENT event,
int32 gen_count);
static acpi_status EcCommand(struct acpi_ec_cookie *sc, EC_COMMAND cmd);
static acpi_status EcRead(struct acpi_ec_cookie *sc, uint8 address,
uint8 *readData);
static acpi_status EcWrite(struct acpi_ec_cookie *sc, uint8 address,
uint8 writeData);
#endif