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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  *
  3.  * Module Name: bn.c
  4.  *   $Revision: 27 $
  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 Plxxe, Suite 330, Boston, MA  02111-1307  USA
  23.  */
  24. #include <acpi.h>
  25. #include "bn.h"
  26. #define _COMPONENT ACPI_BUTTON
  27. MODULE_NAME ("bn")
  28. /*****************************************************************************
  29.  *                            Internal Functions
  30.  *****************************************************************************/
  31. /*****************************************************************************
  32.  *
  33.  * FUNCTION: bn_print
  34.  *
  35.  * PARAMETERS:
  36.  *
  37.  * RETURN:
  38.  *
  39.  * DESCRIPTION: Prints out information on a specific button.
  40.  *
  41.  ****************************************************************************/
  42. void
  43. bn_print (
  44. BN_CONTEXT *button)
  45. {
  46. #ifdef ACPI_DEBUG
  47. acpi_buffer buffer;
  48. PROC_NAME("bn_print");
  49. if (!button) {
  50. return;
  51. }
  52. buffer.length = 256;
  53. buffer.pointer = acpi_os_callocate(buffer.length);
  54. if (!buffer.pointer) {
  55. return;
  56. }
  57. /*
  58.  * Get the full pathname for this ACPI object.
  59.  */
  60. acpi_get_name(button->acpi_handle, ACPI_FULL_PATHNAME, &buffer);
  61. /*
  62.  * Print out basic button information.
  63.  */
  64. ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "+------------------------------------------------------------n"));
  65. switch (button->type) {
  66. case BN_TYPE_POWER_BUTTON:
  67. case BN_TYPE_POWER_BUTTON_FIXED:
  68. ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "| Power_button[%02x]:[%p] %sn", button->device_handle, button->acpi_handle, (char*)buffer.pointer));
  69. break;
  70. case BN_TYPE_SLEEP_BUTTON:
  71. case BN_TYPE_SLEEP_BUTTON_FIXED:
  72. ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "| Sleep_button[%02x]:[%p] %sn", button->device_handle, button->acpi_handle, (char*)buffer.pointer));
  73. break;
  74. case BN_TYPE_LID_SWITCH:
  75. ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "| Lid_switch[%02x]:[%p] %sn", button->device_handle, button->acpi_handle, (char*)buffer.pointer));
  76. break;
  77. }
  78. ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "+------------------------------------------------------------n"));
  79. acpi_os_free(buffer.pointer);
  80. #endif /*ACPI_DEBUG*/
  81. return;
  82. }
  83. /****************************************************************************
  84.  *
  85.  * FUNCTION: bn_add_device
  86.  *
  87.  * PARAMETERS:
  88.  *
  89.  * RETURN:
  90.  *
  91.  * DESCRIPTION:
  92.  *
  93.  ****************************************************************************/
  94. acpi_status
  95. bn_add_device(
  96. BM_HANDLE device_handle,
  97. void **context)
  98. {
  99. acpi_status status = AE_OK;
  100. BM_DEVICE *device = NULL;
  101. BN_CONTEXT *button = NULL;
  102. FUNCTION_TRACE("bn_add_device");
  103. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Adding button device [%02x].n", device_handle));
  104. if (!context || *context) {
  105. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid context.n"));
  106. return_ACPI_STATUS(AE_BAD_PARAMETER);
  107. }
  108. /*
  109.  * Get information on this device.
  110.  */
  111. status = bm_get_device_info( device_handle, &device );
  112. if (ACPI_FAILURE(status)) {
  113. return_ACPI_STATUS(status);
  114. }
  115. /*
  116.  * Allocate a new BN_CONTEXT structure.
  117.  */
  118. button = acpi_os_callocate(sizeof(BN_CONTEXT));
  119. if (!button) {
  120. return_ACPI_STATUS(AE_NO_MEMORY);
  121. }
  122. button->device_handle = device->handle;
  123. button->acpi_handle = device->acpi_handle;
  124. /*
  125.  * Power Button?
  126.  * -------------
  127.  * Either fixed-feature or generic (namespace) types.
  128.  */
  129. if (strncmp(device->id.hid, BN_HID_POWER_BUTTON,
  130. sizeof(BM_DEVICE_HID)) == 0) {
  131. if (device->id.type == BM_TYPE_FIXED_BUTTON) {
  132. button->type = BN_TYPE_POWER_BUTTON_FIXED;
  133. /* Register for fixed-feature events. */
  134. status = acpi_install_fixed_event_handler(
  135. ACPI_EVENT_POWER_BUTTON, bn_notify_fixed,
  136. (void*)button);
  137. }
  138. else {
  139. button->type = BN_TYPE_POWER_BUTTON;
  140. }
  141. }
  142. /*
  143.  * Sleep Button?
  144.  * -------------
  145.  * Either fixed-feature or generic (namespace) types.
  146.  */
  147. else if (strncmp( device->id.hid, BN_HID_SLEEP_BUTTON,
  148. sizeof(BM_DEVICE_HID)) == 0) {
  149. if (device->id.type == BM_TYPE_FIXED_BUTTON) {
  150. button->type = BN_TYPE_SLEEP_BUTTON_FIXED;
  151. /* Register for fixed-feature events. */
  152. status = acpi_install_fixed_event_handler(
  153. ACPI_EVENT_SLEEP_BUTTON, bn_notify_fixed,
  154. (void*)button);
  155. }
  156. else {
  157. button->type = BN_TYPE_SLEEP_BUTTON;
  158. }
  159. }
  160. /*
  161.  * LID Switch?
  162.  * -----------
  163.  */
  164. else if (strncmp( device->id.hid, BN_HID_LID_SWITCH,
  165. sizeof(BM_DEVICE_HID)) == 0) {
  166. button->type = BN_TYPE_LID_SWITCH;
  167. }
  168. status = bn_osl_add_device(button);
  169. if (ACPI_FAILURE(status)) {
  170. goto end;
  171. }
  172. *context = button;
  173. bn_print(button);
  174. end:
  175. if (ACPI_FAILURE(status)) {
  176. acpi_os_free(button);
  177. }
  178. return_ACPI_STATUS(status);
  179. }
  180. /****************************************************************************
  181.  *
  182.  * FUNCTION: bn_remove_device
  183.  *
  184.  * PARAMETERS:
  185.  *
  186.  * RETURN:
  187.  *
  188.  * DESCRIPTION:
  189.  *
  190.  ****************************************************************************/
  191. acpi_status
  192. bn_remove_device(
  193. void **context)
  194. {
  195. acpi_status status = AE_OK;
  196. BN_CONTEXT *button = NULL;
  197. FUNCTION_TRACE("bn_remove_device");
  198. if (!context || !*context) {
  199. return_ACPI_STATUS(AE_BAD_PARAMETER);
  200. }
  201. button = (BN_CONTEXT*)*context;
  202. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Removing button device [%02x].n", button->device_handle));
  203. /*
  204.  * Unregister for fixed-feature events.
  205.  */
  206. switch (button->type) {
  207. case BN_TYPE_POWER_BUTTON_FIXED:
  208. status = acpi_remove_fixed_event_handler(
  209. ACPI_EVENT_POWER_BUTTON, bn_notify_fixed);
  210. break;
  211. case BN_TYPE_SLEEP_BUTTON_FIXED:
  212. status = acpi_remove_fixed_event_handler(
  213. ACPI_EVENT_SLEEP_BUTTON, bn_notify_fixed);
  214. break;
  215. }
  216. bn_osl_remove_device(button);
  217. acpi_os_free(button);
  218. *context = NULL;
  219. return_ACPI_STATUS(status);
  220. }
  221. /*****************************************************************************
  222.  *       External Functions
  223.  *****************************************************************************/
  224. /*****************************************************************************
  225.  *
  226.  * FUNCTION: bn_initialize
  227.  *
  228.  * PARAMETERS: <none>
  229.  *
  230.  * RETURN:
  231.  *
  232.  * DESCRIPTION:
  233.  *
  234.  ****************************************************************************/
  235. acpi_status
  236. bn_initialize (void)
  237. {
  238. BM_DEVICE_ID criteria;
  239. BM_DRIVER driver;
  240. FUNCTION_TRACE("bn_initialize");
  241. MEMSET(&criteria, 0, sizeof(BM_DEVICE_ID));
  242. MEMSET(&driver, 0, sizeof(BM_DRIVER));
  243. driver.notify = &bn_notify;
  244. driver.request = &bn_request;
  245. /*
  246.  * Register for power buttons.
  247.  */
  248. MEMCPY(criteria.hid, BN_HID_POWER_BUTTON, sizeof(BN_HID_POWER_BUTTON));
  249. bm_register_driver(&criteria, &driver);
  250. /*
  251.  * Register for sleep buttons.
  252.  */
  253. MEMCPY(criteria.hid, BN_HID_SLEEP_BUTTON, sizeof(BN_HID_SLEEP_BUTTON));
  254. bm_register_driver(&criteria, &driver);
  255. /*
  256.  * Register for LID switches.
  257.  */
  258. MEMCPY(criteria.hid, BN_HID_LID_SWITCH, sizeof(BN_HID_LID_SWITCH));
  259. bm_register_driver(&criteria, &driver);
  260. return_ACPI_STATUS(AE_OK);
  261. }
  262. /****************************************************************************
  263.  *
  264.  * FUNCTION: bn_terminate
  265.  *
  266.  * PARAMETERS: <none>
  267.  *
  268.  * RETURN:
  269.  *
  270.  * DESCRIPTION:
  271.  *
  272.  ****************************************************************************/
  273. acpi_status
  274. bn_terminate (void)
  275. {
  276. acpi_status status = AE_OK;
  277. BM_DEVICE_ID criteria;
  278. BM_DRIVER driver;
  279. FUNCTION_TRACE("bn_terminate");
  280. MEMSET(&criteria, 0, sizeof(BM_DEVICE_ID));
  281. MEMSET(&driver, 0, sizeof(BM_DRIVER));
  282. driver.notify = &bn_notify;
  283. driver.request = &bn_request;
  284. /*
  285.  * Unregister for power buttons.
  286.  */
  287. MEMCPY(criteria.hid, BN_HID_POWER_BUTTON, sizeof(BN_HID_POWER_BUTTON));
  288. status = bm_unregister_driver(&criteria, &driver);
  289. /*
  290.  * Unregister for sleep buttons.
  291.  */
  292. MEMCPY(criteria.hid, BN_HID_SLEEP_BUTTON, sizeof(BN_HID_SLEEP_BUTTON));
  293. status = bm_unregister_driver(&criteria, &driver);
  294. /*
  295.  * Unregister for LID switches.
  296.  */
  297. MEMCPY(criteria.hid, BN_HID_LID_SWITCH, sizeof(BN_HID_LID_SWITCH));
  298. status = bm_unregister_driver(&criteria, &driver);
  299. return_ACPI_STATUS(status);
  300. }
  301. /****************************************************************************
  302.  *
  303.  * FUNCTION: bn_notify_fixed
  304.  *
  305.  * PARAMETERS: <none>
  306.  *
  307.  * RETURN:
  308.  *
  309.  * DESCRIPTION:
  310.  *
  311.  ****************************************************************************/
  312. acpi_status
  313. bn_notify_fixed (
  314. void *context)
  315. {
  316. acpi_status status = AE_OK;
  317. FUNCTION_TRACE("bn_notify_fixed");
  318. if (!context) {
  319. return_ACPI_STATUS(AE_BAD_PARAMETER);
  320. }
  321. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Status change event detected.n"));
  322. status = bn_osl_generate_event(BN_NOTIFY_STATUS_CHANGE,
  323. ((BN_CONTEXT*)context));
  324. return_ACPI_STATUS(status);
  325. }
  326. /****************************************************************************
  327.  *
  328.  * FUNCTION: bn_notify
  329.  *
  330.  * PARAMETERS: <none>
  331.  *
  332.  * RETURN:
  333.  *
  334.  * DESCRIPTION:
  335.  *
  336.  ****************************************************************************/
  337. acpi_status
  338. bn_notify (
  339. BM_NOTIFY notify_type,
  340. BM_HANDLE device_handle,
  341. void **context)
  342. {
  343. acpi_status status = AE_OK;
  344. FUNCTION_TRACE("bn_notify");
  345. if (!context) {
  346. return_ACPI_STATUS(AE_BAD_PARAMETER);
  347. }
  348. switch (notify_type) {
  349. case BM_NOTIFY_DEVICE_ADDED:
  350. status = bn_add_device(device_handle, context);
  351. break;
  352. case BM_NOTIFY_DEVICE_REMOVED:
  353. status = bn_remove_device(context);
  354. break;
  355. case BN_NOTIFY_STATUS_CHANGE:
  356. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Status change event detected.n"));
  357. status = bn_osl_generate_event(BN_NOTIFY_STATUS_CHANGE,
  358. ((BN_CONTEXT*)*context));
  359. break;
  360. default:
  361. status = AE_SUPPORT;
  362. break;
  363. }
  364. return_ACPI_STATUS(status);
  365. }
  366. /****************************************************************************
  367.  *
  368.  * FUNCTION: bn_request
  369.  *
  370.  * PARAMETERS:
  371.  *
  372.  * RETURN:
  373.  *
  374.  * DESCRIPTION:
  375.  *
  376.  ****************************************************************************/
  377. acpi_status
  378. bn_request (
  379. BM_REQUEST *request,
  380. void *context)
  381. {
  382. acpi_status status = AE_OK;
  383. FUNCTION_TRACE("bn_request");
  384. /*
  385.  * Must have a valid request structure and context.
  386.  */
  387. if (!request || !context) {
  388. return_ACPI_STATUS(AE_BAD_PARAMETER);
  389. }
  390. /*
  391.  * Handle Request:
  392.  * ---------------
  393.  */
  394. switch (request->command) {
  395. default:
  396. status = AE_SUPPORT;
  397. break;
  398. }
  399. request->status = status;
  400. return_ACPI_STATUS(status);
  401. }