⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ec.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  ec.c - Embedded controller support * *  Copyright (C) 2000 Andrew Henroid * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include <linux/kernel.h>#include <linux/acpi.h>#include <linux/slab.h>#include "acpi.h"#include "driver.h"#include "ec.h"#define _COMPONENT	OS_DEPENDENT	MODULE_NAME	("ec")#define ACPI_EC_HID	"PNP0C09"enum{	ACPI_EC_SMI = 0x40,	ACPI_EC_SCI = 0x20,	ACPI_EC_BURST = 0x10,	ACPI_EC_CMD = 0x08,	ACPI_EC_IBF = 0x02,	ACPI_EC_OBF = 0x01};enum{	ACPI_EC_READ = 0x80,	ACPI_EC_WRITE = 0x81,	ACPI_EC_BURST_ENABLE = 0x82,	ACPI_EC_BURST_DISABLE = 0x83,	ACPI_EC_QUERY = 0x84,};typedef struct{	ACPI_HANDLE		acpi_handle;	u32			gpe_bit;	ACPI_IO_ADDRESS 	status_port;	ACPI_IO_ADDRESS 	data_port;	u32			need_global_lock;} ec_context_t;typedef struct {    ec_context_t	*ec;    u8			data;} EC_QUERY_DATA;static char object_name[] = {'_', 'Q', '0', '0', '\0'};static char hex[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};static ACPI_STATUSec_io_wait (    ec_context_t              *ec,    EC_EVENT                wait_event){    EC_STATUS               ec_status = 0;    UINT32                  i = 100;    if (!ec || ((wait_event != EC_EVENT_OUTPUT_BUFFER_FULL)         && (wait_event != EC_EVENT_INPUT_BUFFER_EMPTY)))        return(AE_BAD_PARAMETER);    /*      * Wait for Event:     * ---------------     * Poll the EC status register waiting for the event to occur.     * Note that we'll wait a maximum of 1ms in 10us chunks.     */    switch (wait_event) {    case EC_EVENT_OUTPUT_BUFFER_FULL:        do {            ec_status = acpi_os_in8(ec->status_port);            if (ec_status & EC_FLAG_OUTPUT_BUFFER)                return(AE_OK);            acpi_os_sleep_usec(10);        } while (--i>0);        break;    case EC_EVENT_INPUT_BUFFER_EMPTY:        do {            ec_status = acpi_os_in8(ec->status_port);            if (!(ec_status & EC_FLAG_INPUT_BUFFER))                return(AE_OK);            acpi_os_sleep_usec(10);        } while (--i>0);        break;    }    return(AE_TIME);}static ACPI_STATUSec_io_read (    ec_context_t              *ec,    ACPI_IO_ADDRESS         io_port,    UINT8                   *data,    EC_EVENT                wait_event){    ACPI_STATUS             status = AE_OK;    if (!ec || !data)        return(AE_BAD_PARAMETER);    *data = acpi_os_in8(io_port);    if (wait_event)        status = ec_io_wait(ec, wait_event);    return(status);}static ACPI_STATUSec_io_write (    ec_context_t              *ec,    ACPI_IO_ADDRESS         io_port,    UINT8                   data,    EC_EVENT                wait_event){    ACPI_STATUS             status = AE_OK;    if (!ec)        return(AE_BAD_PARAMETER);    acpi_os_out8(io_port, data);    if (wait_event)        status = ec_io_wait(ec, wait_event);    return(status);}static ACPI_STATUSec_read (    ec_context_t              *ec,    UINT8                   address,    UINT8                   *data){    ACPI_STATUS             status = AE_OK;    FUNCTION_TRACE("ec_read");    if (!ec || !data)        return_ACPI_STATUS(AE_BAD_PARAMETER);    status = ec_io_write(ec, ec->status_port, EC_COMMAND_READ, EC_EVENT_INPUT_BUFFER_EMPTY);    if (ACPI_FAILURE(status)) {        DEBUG_PRINT(ACPI_WARN, ("Unable to send 'read command' to EC.\n"));        return_ACPI_STATUS(status);    }    status = ec_io_write(ec, ec->data_port, address, EC_EVENT_OUTPUT_BUFFER_FULL);    if (ACPI_FAILURE(status)) {        DEBUG_PRINT(ACPI_WARN, ("Unable to send 'read address' to EC.\n"));        return_ACPI_STATUS(status);    }    status = ec_io_read(ec, ec->data_port, data, EC_EVENT_NONE);    DEBUG_PRINT(ACPI_INFO, ("Read data[0x%02x] from address[0x%02x] on ec.\n", (*data), address));    return_ACPI_STATUS(status);}static ACPI_STATUSec_write (    ec_context_t              *ec,    UINT8                   address,    UINT8                   data){    ACPI_STATUS             status = AE_OK;    FUNCTION_TRACE("ec_write");    if (!ec)        return_ACPI_STATUS(AE_BAD_PARAMETER);    status = ec_io_write(ec, ec->status_port, EC_COMMAND_WRITE, EC_EVENT_INPUT_BUFFER_EMPTY);    if (ACPI_FAILURE(status)) {        DEBUG_PRINT(ACPI_WARN, ("Unable to send 'write command' to EC.\n"));        return_ACPI_STATUS(status);    }    status = ec_io_write(ec, ec->data_port, address, EC_EVENT_INPUT_BUFFER_EMPTY);    if (ACPI_FAILURE(status)) {        DEBUG_PRINT(ACPI_WARN, ("Unable to send 'write address' to EC.\n"));        return_ACPI_STATUS(status);    }    status = ec_io_write(ec, ec->data_port, data, EC_EVENT_INPUT_BUFFER_EMPTY);    if (ACPI_FAILURE(status)) {        DEBUG_PRINT(ACPI_WARN, ("Unable to send 'write data' to EC.\n"));        return_ACPI_STATUS(status);    }    DEBUG_PRINT(ACPI_INFO, ("Wrote data[0x%02x] to address[0x%02x] on ec.\n", data, address));    return_ACPI_STATUS(status);}static ACPI_STATUSec_transaction (    ec_context_t              *ec,    EC_REQUEST              *request){    ACPI_STATUS             status = AE_OK;    FUNCTION_TRACE("ec_transaction");    if (!ec || !request)        return_ACPI_STATUS(AE_BAD_PARAMETER);    /*     * Obtaining semaphore (mutex) to serialize all EC transactions.     */    /*    DEBUG_PRINT(ACPI_INFO, ("Calling acpi_os_wait_semaphore(%p, 1, %d)\n", ec->mutex, EC_DEFAULT_TIMEOUT));    status = acpi_os_wait_semaphore(ec->mutex, 1, EC_DEFAULT_TIMEOUT);    if (ACPI_FAILURE(status))        return_ACPI_STATUS(status);    */    /*     * Perform the transaction.     */    switch (request->command) {    case EC_COMMAND_READ:        status = ec_read(ec, request->address, &(request->data));        break;    case EC_COMMAND_WRITE:        status = ec_write(ec, request->address, request->data);        break;    default:        status = AE_SUPPORT;        break;    }    /*     * Signal the semaphore (mutex) to indicate transaction completion.     */    /*    DEBUG_PRINT(ACPI_INFO, ("Calling acpi_os_signal_semaphore(%p, 1)\n", ec->mutex));    acpi_os_signal_semaphore(ec->mutex, 1);    */    return_ACPI_STATUS(status);}static ACPI_STATUS ec_space_setup (    ACPI_HANDLE                 region_handle,    UINT32                      function,    void                        *handler_context,    void                        **return_context){	// TODO: What is this function for?	/* 	 * The ec object is in the handler context and is needed	 * when calling the ec_space_handler.	 */	*return_context = handler_context;    return AE_OK;}static voidec_query_handler (    void                    *context){    ACPI_STATUS             status = AE_OK;    EC_QUERY_DATA           *ec_q = (EC_QUERY_DATA*)context;    FUNCTION_TRACE("ec_query_handler");    if (!ec_q || !ec_q->ec) {        DEBUG_PRINT(ACPI_ERROR, ("Invalid (NULL) context.\n"));        return_VOID;    }    /*     * Evaluate _Qxx:     * --------------     * Evaluate corresponding _Qxx method.  Note that a zero query     * value indicates a spurious EC_SCI (no such thing as _Q00).

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -