ectransx.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:8k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  *
  3.  * Module Name: ectransx.c
  4.  *   $Revision: 24 $
  5.  *
  6.  *****************************************************************************/
  7. /*
  8.  *  Copyright (C) 2000, 2001 Andrew Grover
  9.  *
  10.  *  This program is free software; you can redistribute it and/or modify
  11.  *  it under the terms of the GNU General Public License as published by
  12.  *  the Free Software Foundation; either version 2 of the License, or
  13.  *  (at your option) any later version.
  14.  *
  15.  *  This program is distributed in the hope that it will be useful,
  16.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  *  GNU General Public License for more details.
  19.  *
  20.  *  You should have received a copy of the GNU General Public License
  21.  *  along with this program; if not, write to the Free Software
  22.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  23.  */
  24. #include <acpi.h>
  25. #include "ec.h"
  26. #define _COMPONENT ACPI_EC
  27. MODULE_NAME             ("ectransx")
  28. /****************************************************************************
  29.  *
  30.  * FUNCTION:    ec_io_wait
  31.  *
  32.  * PARAMETERS:
  33.  *
  34.  * RETURN:
  35.  *
  36.  * DESCRIPTION:
  37.  *
  38.  ****************************************************************************/
  39. acpi_status
  40. ec_io_wait (
  41. EC_CONTEXT              *ec,
  42. EC_EVENT                wait_event)
  43. {
  44. EC_STATUS               ec_status = 0;
  45. u32                     i = 100;
  46. if (!ec || ((wait_event != EC_EVENT_OUTPUT_BUFFER_FULL)
  47. && (wait_event != EC_EVENT_INPUT_BUFFER_EMPTY))) {
  48. return(AE_BAD_PARAMETER);
  49. }
  50. /*
  51.  * Wait for Event:
  52.  * ---------------
  53.  * Poll the EC status register waiting for the event to occur.
  54.  * Note that we'll wait a maximum of 1ms in 10us chunks.
  55.  */
  56. switch (wait_event) {
  57. case EC_EVENT_OUTPUT_BUFFER_FULL:
  58. do {
  59. acpi_os_read_port(ec->status_port, &ec_status, 8);
  60. if (ec_status & EC_FLAG_OUTPUT_BUFFER) {
  61. return(AE_OK);
  62. }
  63. acpi_os_stall(10);
  64. } while (--i>0);
  65. break;
  66. case EC_EVENT_INPUT_BUFFER_EMPTY:
  67. do {
  68. acpi_os_read_port(ec->status_port, &ec_status, 8);
  69. if (!(ec_status & EC_FLAG_INPUT_BUFFER)) {
  70. return(AE_OK);
  71. }
  72. acpi_os_stall(10);
  73. } while (--i>0);
  74. break;
  75. }
  76. return(AE_TIME);
  77. }
  78. /****************************************************************************
  79.  *
  80.  * FUNCTION:    ec_io_read
  81.  *
  82.  * PARAMETERS:
  83.  *
  84.  * RETURN:
  85.  *
  86.  * DESCRIPTION:
  87.  *
  88.  ****************************************************************************/
  89. acpi_status
  90. ec_io_read (
  91. EC_CONTEXT              *ec,
  92. ACPI_IO_ADDRESS         io_port,
  93. u8                      *data,
  94. EC_EVENT                wait_event)
  95. {
  96. acpi_status             status = AE_OK;
  97. if (!ec || !data) {
  98. return(AE_BAD_PARAMETER);
  99. }
  100. acpi_os_read_port(io_port, (u32*) data, 8);
  101. if (wait_event) {
  102. status = ec_io_wait(ec, wait_event);
  103. }
  104. return(status);
  105. }
  106. /****************************************************************************
  107.  *
  108.  * FUNCTION:    ec_io_write
  109.  *
  110.  * PARAMETERS:
  111.  *
  112.  * RETURN:
  113.  *
  114.  * DESCRIPTION:
  115.  *
  116.  ****************************************************************************/
  117. acpi_status
  118. ec_io_write (
  119. EC_CONTEXT              *ec,
  120. ACPI_IO_ADDRESS         io_port,
  121. u8                      data,
  122. EC_EVENT                wait_event)
  123. {
  124. acpi_status             status = AE_OK;
  125. if (!ec) {
  126. return(AE_BAD_PARAMETER);
  127. }
  128. acpi_os_write_port(io_port, data, 8);
  129. if (wait_event) {
  130. status = ec_io_wait(ec, wait_event);
  131. }
  132. return(status);
  133. }
  134. /****************************************************************************
  135.  *
  136.  * FUNCTION:    ec_read
  137.  *
  138.  * PARAMETERS:
  139.  *
  140.  * RETURN:
  141.  *
  142.  * DESCRIPTION:
  143.  *
  144.  ****************************************************************************/
  145. acpi_status
  146. ec_read (
  147. EC_CONTEXT              *ec,
  148. u8                      address,
  149. u8                      *data)
  150. {
  151. acpi_status             status = AE_OK;
  152. FUNCTION_TRACE("ec_read");
  153. if (!ec || !data) {
  154. return_ACPI_STATUS(AE_BAD_PARAMETER);
  155. }
  156. if (ec->use_global_lock) {
  157. status = acpi_acquire_global_lock();
  158. if (ACPI_FAILURE(status)) {
  159. ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Could not acquire Global Lockn"));
  160. return_ACPI_STATUS(status);
  161. }
  162. }
  163. status = ec_io_write(ec, ec->command_port, EC_COMMAND_READ,
  164. EC_EVENT_INPUT_BUFFER_EMPTY);
  165. if (ACPI_FAILURE(status)) {
  166. ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Unable to send 'read command' to EC.n"));
  167. return_ACPI_STATUS(status);
  168. }
  169. status = ec_io_write(ec, ec->data_port, address,
  170. EC_EVENT_OUTPUT_BUFFER_FULL);
  171. if (ACPI_FAILURE(status)) {
  172. ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Unable to send 'read address' to EC.n"));
  173. return_ACPI_STATUS(status);
  174. }
  175. status = ec_io_read(ec, ec->data_port, data, EC_EVENT_NONE);
  176. if (ec->use_global_lock) {
  177. acpi_release_global_lock();
  178. }
  179. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Read data [%02x] from address [%02x] on ec [%02x].n", (*data), address, ec->device_handle));
  180. return_ACPI_STATUS(status);
  181. }
  182. /****************************************************************************
  183.  *
  184.  * FUNCTION:    ec_write
  185.  *
  186.  * PARAMETERS:
  187.  *
  188.  * RETURN:
  189.  *
  190.  * DESCRIPTION:
  191.  *
  192.  ****************************************************************************/
  193. acpi_status
  194. ec_write (
  195. EC_CONTEXT              *ec,
  196. u8                      address,
  197. u8                      data)
  198. {
  199. acpi_status             status = AE_OK;
  200. FUNCTION_TRACE("ec_write");
  201. if (!ec)
  202. return_ACPI_STATUS(AE_BAD_PARAMETER);
  203. if (ec->use_global_lock) {
  204. status = acpi_acquire_global_lock();
  205. if (ACPI_FAILURE(status)) {
  206. ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Could not acquire Global Lockn"));
  207. return_ACPI_STATUS(status);
  208. }
  209. }
  210. status = ec_io_write(ec, ec->command_port, EC_COMMAND_WRITE,
  211. EC_EVENT_INPUT_BUFFER_EMPTY);
  212. if (ACPI_FAILURE(status)) {
  213. ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Unable to send 'write command' to EC.n"));
  214. return_ACPI_STATUS(status);
  215. }
  216. status = ec_io_write(ec, ec->data_port, address,
  217. EC_EVENT_INPUT_BUFFER_EMPTY);
  218. if (ACPI_FAILURE(status)) {
  219. ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Unable to send 'write address' to EC.n"));
  220. return_ACPI_STATUS(status);
  221. }
  222. status = ec_io_write(ec, ec->data_port, data,
  223. EC_EVENT_INPUT_BUFFER_EMPTY);
  224. if (ACPI_FAILURE(status)) {
  225. ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Unable to send 'write data' to EC.n"));
  226. return_ACPI_STATUS(status);
  227. }
  228. if (ec->use_global_lock) {
  229. acpi_release_global_lock();
  230. }
  231. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Wrote data [%02x] to address [%02x] on ec [%02x].n", data, address, ec->device_handle));
  232. return_ACPI_STATUS(status);
  233. }
  234. /****************************************************************************
  235.  *
  236.  * FUNCTION:    ec_transaction
  237.  *
  238.  * PARAMETERS:
  239.  *
  240.  * RETURN:
  241.  *
  242.  * DESCRIPTION:
  243.  *
  244.  ****************************************************************************/
  245. acpi_status
  246. ec_transaction (
  247. EC_CONTEXT              *ec,
  248. EC_REQUEST              *request)
  249. {
  250. acpi_status             status = AE_OK;
  251. FUNCTION_TRACE("ec_transaction");
  252. if (!ec || !request) {
  253. return_ACPI_STATUS(AE_BAD_PARAMETER);
  254. }
  255. /*
  256.  * Obtain mutex to serialize all EC transactions.
  257.  */
  258. status = acpi_os_wait_semaphore(ec->mutex, 1, EC_DEFAULT_TIMEOUT);
  259. if (ACPI_FAILURE(status)) {
  260. return_ACPI_STATUS(status);
  261. }
  262. /*
  263.  * Perform the transaction.
  264.  */
  265. switch (request->command) {
  266. case EC_COMMAND_READ:
  267. status = ec_read(ec, request->address, &(request->data));
  268. break;
  269. case EC_COMMAND_WRITE:
  270. status = ec_write(ec, request->address, request->data);
  271. break;
  272. default:
  273. status = AE_SUPPORT;
  274. break;
  275. }
  276. /*
  277.  * Signal the mutex to indicate transaction completion.
  278.  */
  279. acpi_os_signal_semaphore(ec->mutex, 1);
  280. return_ACPI_STATUS(status);
  281. }