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

嵌入式Linux

开发平台:

Unix_Linux

  1. /******************************************************************************
  2.  *
  3.  * Module Name: bt_osl.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. /*
  25.  * Changes:
  26.  * Brendan Burns <bburns@wso.williams.edu> 2000-11-15
  27.  * - added proc battery interface
  28.  * - parse returned data from _BST and _BIF
  29.  * Andy Grover <andrew.grover@intel.com> 2000-12-8
  30.  * - improved proc interface
  31.  */
  32. #include <linux/kernel.h>
  33. #include <linux/module.h>
  34. #include <linux/init.h>
  35. #include <linux/types.h>
  36. #include <linux/proc_fs.h>
  37. #include <acpi.h>
  38. #include "bt.h"
  39. MODULE_AUTHOR("Andrew Grover");
  40. MODULE_DESCRIPTION("ACPI Component Architecture (CA) - Control Method Battery Driver");
  41. MODULE_LICENSE("GPL");
  42. #define BT_PROC_ROOT "battery"
  43. #define BT_PROC_STATUS "status"
  44. #define BT_PROC_INFO "info"
  45. extern struct proc_dir_entry *bm_proc_root;
  46. static struct proc_dir_entry *bt_proc_root = NULL;
  47. /****************************************************************************
  48.  *
  49.  * FUNCTION: bt_osl_proc_read_info
  50.  *
  51.  ****************************************************************************/
  52. static int
  53. bt_osl_proc_read_info (
  54. char *page,
  55. char **start,
  56. off_t off,
  57. int  count,
  58. int  *eof,
  59. void *context)
  60. {
  61. BT_CONTEXT *battery = NULL;
  62. BT_BATTERY_INFO  *battery_info = NULL;
  63. char *p = page;
  64. int  len = 0;
  65. if (!context || (off != 0)) {
  66. goto end;
  67. }
  68. battery = (BT_CONTEXT*)context;
  69. /*
  70.  * Battery Present?
  71.  * ----------------
  72.  */
  73. if (!battery->is_present) {
  74. p += sprintf(p, "Present:                 non");
  75. goto end;
  76. }
  77. else {
  78. p += sprintf(p, "Present:                 yesn");
  79. }
  80. /*
  81.  * Get Battery Information:
  82.  * ------------------------
  83.  */
  84. if (ACPI_FAILURE(bt_get_info(battery, &battery_info))) {
  85. p += sprintf(p, "Error reading battery information (_BIF)n");
  86. goto end;
  87. }
  88. if (battery_info->design_capacity == BT_UNKNOWN) {
  89. p += sprintf(p, "Design Capacity:         unknownn");
  90. }
  91. else {
  92. p += sprintf(p, "Design Capacity:         %d %shn",
  93.  (u32)battery_info->design_capacity,
  94.  battery->power_units);
  95. }
  96. if (battery_info->last_full_capacity == BT_UNKNOWN) {
  97. p += sprintf(p, "Last Full Capacity:      unknownn");
  98. }
  99. else {
  100. p += sprintf(p, "Last Full Capacity:      %d %shn",
  101.  (u32)battery_info->last_full_capacity,
  102.  battery->power_units);
  103. }
  104. if (battery_info->battery_technology == 0) {
  105. p += sprintf(p, "Battery Technology:      primary (non-rechargeable)n");
  106. }
  107. else if (battery_info->battery_technology == 1) {
  108. p += sprintf(p, "Battery Technology:      secondary (rechargeable)n");
  109. }
  110. else {
  111. p += sprintf(p, "Battery Technology:      unknownn");
  112. }
  113. if (battery_info->design_voltage == BT_UNKNOWN) {
  114. p += sprintf(p, "Design Voltage:          unknownn");
  115. }
  116. else {
  117. p += sprintf(p, "Design Voltage:          %d mVn",
  118.  (u32)battery_info->design_voltage);
  119. }
  120. p += sprintf(p, "Design Capacity Warning: %d %shn",
  121. (u32)battery_info->design_capacity_warning,
  122. battery->power_units);
  123. p += sprintf(p, "Design Capacity Low:     %d %shn",
  124. (u32)battery_info->design_capacity_low,
  125. battery->power_units);
  126. p += sprintf(p, "Capacity Granularity 1:  %d %shn",
  127. (u32)battery_info->battery_capacity_granularity_1,
  128. battery->power_units);
  129. p += sprintf(p, "Capacity Granularity 2:  %d %shn",
  130. (u32)battery_info->battery_capacity_granularity_2,
  131. battery->power_units);
  132. p += sprintf(p, "Model Number:            %sn",
  133. battery_info->model_number);
  134. p += sprintf(p, "Serial Number:           %sn",
  135. battery_info->serial_number);
  136. p += sprintf(p, "Battery Type:            %sn",
  137. battery_info->battery_type);
  138. p += sprintf(p, "OEM Info:                %sn",
  139. battery_info->oem_info);
  140. end:
  141. len = (p - page);
  142. if (len <= off+count) *eof = 1;
  143. *start = page + off;
  144. len -= off;
  145. if (len>count) len = count;
  146. if (len<0) len = 0;
  147. acpi_os_free(battery_info);
  148. return(len);
  149. }
  150. /****************************************************************************
  151.  *
  152.  * FUNCTION: bt_osl_proc_read_status
  153.  *
  154.  ****************************************************************************/
  155. static int
  156. bt_osl_proc_read_status (
  157. char *page,
  158. char **start,
  159. off_t off,
  160. int  count,
  161. int  *eof,
  162. void *context)
  163. {
  164. BT_CONTEXT *battery = NULL;
  165. BT_BATTERY_STATUS *battery_status = NULL;
  166. char *p = page;
  167. int  len = 0;
  168. if (!context || (off != 0)) {
  169. goto end;
  170. }
  171. battery = (BT_CONTEXT*)context;
  172. /*
  173.  * Battery Present?
  174.  * ----------------
  175.  */
  176. if (!battery->is_present) {
  177. p += sprintf(p, "Present:                 non");
  178. goto end;
  179. }
  180. else {
  181. p += sprintf(p, "Present:                 yesn");
  182. }
  183. /*
  184.  * Get Battery Status:
  185.  * -------------------
  186.  */
  187. if (ACPI_FAILURE(bt_get_status(battery, &battery_status))) {
  188. p += sprintf(p, "Error reading battery status (_BST)n");
  189. goto end;
  190. }
  191. /*
  192.  * Store Data:
  193.  * -----------
  194.  */
  195. if (!battery_status->state) {
  196. p += sprintf(p, "State:                   okn");
  197. }
  198. else {
  199. if (battery_status->state & 0x1)
  200. p += sprintf(p, "State:                   dischargingn");
  201. if (battery_status->state & 0x2)
  202. p += sprintf(p, "State:                   chargingn");
  203. if (battery_status->state & 0x4)
  204. p += sprintf(p, "State:                   critically lown");
  205. }
  206. if (battery_status->present_rate == BT_UNKNOWN) {
  207. p += sprintf(p, "Present Rate:            unknownn");
  208. }
  209. else {
  210. p += sprintf(p, "Present Rate:            %d %sn",
  211. (u32)battery_status->present_rate,
  212. battery->power_units);
  213. }
  214. if (battery_status->remaining_capacity == BT_UNKNOWN) {
  215. p += sprintf(p, "Remaining Capacity:      unknownn");
  216. }
  217. else {
  218. p += sprintf(p, "Remaining Capacity:      %d %shn",
  219. (u32)battery_status->remaining_capacity,
  220. battery->power_units);
  221. }
  222. if (battery_status->present_voltage == BT_UNKNOWN) {
  223. p += sprintf(p, "Battery Voltage:         unknownn");
  224. }
  225. else {
  226. p += sprintf(p, "Battery Voltage:         %d mVn",
  227. (u32)battery_status->present_voltage);
  228. }
  229. end:
  230. len = (p - page);
  231. if (len <= off+count) *eof = 1;
  232. *start = page + off;
  233. len -= off;
  234. if (len>count) len = count;
  235. if (len<0) len = 0;
  236. acpi_os_free(battery_status);
  237. return(len);
  238. }
  239. /****************************************************************************
  240.  *
  241.  * FUNCTION: bt_osl_add_device
  242.  *
  243.  ****************************************************************************/
  244. acpi_status
  245. bt_osl_add_device(
  246. BT_CONTEXT *battery)
  247. {
  248. struct proc_dir_entry *proc_entry = NULL;
  249. if (!battery) {
  250. return(AE_BAD_PARAMETER);
  251. }
  252. if (battery->is_present) {
  253. printk("ACPI: Battery socket found, battery presentn");
  254. }
  255. else {
  256. printk("ACPI: Battery socket found, battery absentn");
  257. }
  258. proc_entry = proc_mkdir(battery->uid, bt_proc_root);
  259. if (!proc_entry) {
  260. return(AE_ERROR);
  261. }
  262. create_proc_read_entry(BT_PROC_STATUS, S_IFREG | S_IRUGO,
  263. proc_entry, bt_osl_proc_read_status, (void*)battery);
  264. create_proc_read_entry(BT_PROC_INFO, S_IFREG | S_IRUGO,
  265. proc_entry, bt_osl_proc_read_info, (void*)battery);
  266. return(AE_OK);
  267. }
  268. /****************************************************************************
  269.  *
  270.  * FUNCTION: bt_osl_remove_device
  271.  *
  272.  ****************************************************************************/
  273. acpi_status
  274. bt_osl_remove_device (
  275. BT_CONTEXT *battery)
  276. {
  277. char proc_entry[64];
  278. if (!battery) {
  279. return(AE_BAD_PARAMETER);
  280. }
  281. sprintf(proc_entry, "%s/%s", battery->uid, BT_PROC_INFO);
  282. remove_proc_entry(proc_entry, bt_proc_root);
  283. sprintf(proc_entry, "%s/%s", battery->uid, BT_PROC_STATUS);
  284. remove_proc_entry(proc_entry, bt_proc_root);
  285. sprintf(proc_entry, "%s", battery->uid);
  286. remove_proc_entry(proc_entry, bt_proc_root);
  287. return(AE_OK);
  288. }
  289. /****************************************************************************
  290.  *
  291.  * FUNCTION: bt_osl_generate_event
  292.  *
  293.  ****************************************************************************/
  294. acpi_status
  295. bt_osl_generate_event (
  296. u32 event,
  297. BT_CONTEXT *battery)
  298. {
  299. acpi_status status = AE_OK;
  300. if (!battery) {
  301. return(AE_BAD_PARAMETER);
  302. }
  303. switch (event) {
  304. case BT_NOTIFY_STATUS_CHANGE:
  305. case BT_NOTIFY_INFORMATION_CHANGE:
  306. status = bm_osl_generate_event(battery->device_handle,
  307. BT_PROC_ROOT, battery->uid, event, 0);
  308. break;
  309. default:
  310. return(AE_BAD_PARAMETER);
  311. break;
  312. }
  313. return(status);
  314. }
  315. /****************************************************************************
  316.  *
  317.  * FUNCTION: bt_osl_init
  318.  *
  319.  * PARAMETERS: <none>
  320.  *
  321.  * RETURN: 0: Success
  322.  *
  323.  * DESCRIPTION: Module initialization.
  324.  *
  325.  ****************************************************************************/
  326. static int __init
  327. bt_osl_init (void)
  328. {
  329. acpi_status status = AE_OK;
  330. /* abort if no busmgr */
  331. if (!bm_proc_root)
  332. return -ENODEV;
  333. bt_proc_root = proc_mkdir(BT_PROC_ROOT, bm_proc_root);
  334. if (!bt_proc_root) {
  335. status = AE_ERROR;
  336. }
  337. else {
  338. status = bt_initialize();
  339. if (ACPI_FAILURE(status)) {
  340. remove_proc_entry(BT_PROC_ROOT, bm_proc_root);
  341. }
  342. }
  343. return (ACPI_SUCCESS(status)) ? 0 : -ENODEV;
  344. }
  345. /****************************************************************************
  346.  *
  347.  * FUNCTION: bt_osl_cleanup
  348.  *
  349.  * PARAMETERS: <none>
  350.  *
  351.  * RETURN: <none>
  352.  *
  353.  * DESCRIPTION: Module cleanup.
  354.  *
  355.  ****************************************************************************/
  356. static void __exit
  357. bt_osl_cleanup (void)
  358. {
  359. bt_terminate();
  360. if (bt_proc_root) {
  361. remove_proc_entry(BT_PROC_ROOT, bm_proc_root);
  362. }
  363. return;
  364. }
  365. module_init(bt_osl_init);
  366. module_exit(bt_osl_cleanup);