2 * acpi_battery.c - ACPI Battery Driver ($Revision: 37 $)
4 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
5 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or (at
12 * your option) any later version.
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
23 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
26 #include <linux/kernel.h>
27 #include <linux/module.h>
28 #include <linux/init.h>
29 #include <linux/types.h>
30 #include <linux/proc_fs.h>
31 #include <linux/seq_file.h>
32 #include <asm/uaccess.h>
34 #include <acpi/acpi_bus.h>
35 #include <acpi/acpi_drivers.h>
37 #define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF
39 #define ACPI_BATTERY_COMPONENT 0x00040000
40 #define ACPI_BATTERY_CLASS "battery"
41 #define ACPI_BATTERY_DEVICE_NAME "Battery"
42 #define ACPI_BATTERY_NOTIFY_STATUS 0x80
43 #define ACPI_BATTERY_NOTIFY_INFO 0x81
44 #define ACPI_BATTERY_UNITS_WATTS "mW"
45 #define ACPI_BATTERY_UNITS_AMPS "mA"
47 #define _COMPONENT ACPI_BATTERY_COMPONENT
49 #define ACPI_BATTERY_UPDATE_TIME 0
51 #define ACPI_BATTERY_NONE_UPDATE 0
52 #define ACPI_BATTERY_EASY_UPDATE 1
53 #define ACPI_BATTERY_INIT_UPDATE 2
55 ACPI_MODULE_NAME("battery");
57 MODULE_AUTHOR("Paul Diefenbaugh");
58 MODULE_DESCRIPTION("ACPI Battery Driver");
59 MODULE_LICENSE("GPL");
61 static unsigned int update_time = ACPI_BATTERY_UPDATE_TIME;
63 /* 0 - every time, > 0 - by update_time */
64 module_param(update_time, uint, 0644);
66 extern struct proc_dir_entry *acpi_lock_battery_dir(void);
67 extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
69 static int acpi_battery_add(struct acpi_device *device);
70 static int acpi_battery_remove(struct acpi_device *device, int type);
71 static int acpi_battery_resume(struct acpi_device *device);
73 static const struct acpi_device_id battery_device_ids[] = {
77 MODULE_DEVICE_TABLE(acpi, battery_device_ids);
79 static struct acpi_driver acpi_battery_driver = {
81 .class = ACPI_BATTERY_CLASS,
82 .ids = battery_device_ids,
84 .add = acpi_battery_add,
85 .resume = acpi_battery_resume,
86 .remove = acpi_battery_remove,
90 enum acpi_battery_files {
91 ACPI_BATTERY_INFO = 0,
94 ACPI_BATTERY_NUMFILES,
98 struct acpi_device *device;
101 unsigned long update_time[ACPI_BATTERY_NUMFILES];
104 int remaining_capacity;
108 int last_full_capacity;
111 int design_capacity_warning;
112 int design_capacity_low;
113 int capacity_granularity_1;
114 int capacity_granularity_2;
115 char model_number[32];
116 char serial_number[32];
122 u8 update[ACPI_BATTERY_NUMFILES];
125 inline int acpi_battery_present(struct acpi_battery *battery)
127 return battery->device->status.battery_present;
130 inline char *acpi_battery_power_units(struct acpi_battery *battery)
132 if (battery->power_unit)
133 return ACPI_BATTERY_UNITS_AMPS;
135 return ACPI_BATTERY_UNITS_WATTS;
138 inline acpi_handle acpi_battery_handle(struct acpi_battery *battery)
140 return battery->device->handle;
143 /* --------------------------------------------------------------------------
145 -------------------------------------------------------------------------- */
147 static void acpi_battery_check_result(struct acpi_battery *battery, int result)
153 battery->init_update = 1;
157 struct acpi_offsets {
158 size_t offset; /* offset inside struct acpi_sbs_battery */
159 u8 mode; /* int or string? */
162 static struct acpi_offsets state_offsets[] = {
163 {offsetof(struct acpi_battery, state), 0},
164 {offsetof(struct acpi_battery, present_rate), 0},
165 {offsetof(struct acpi_battery, remaining_capacity), 0},
166 {offsetof(struct acpi_battery, present_voltage), 0},
169 static struct acpi_offsets info_offsets[] = {
170 {offsetof(struct acpi_battery, power_unit), 0},
171 {offsetof(struct acpi_battery, design_capacity), 0},
172 {offsetof(struct acpi_battery, last_full_capacity), 0},
173 {offsetof(struct acpi_battery, technology), 0},
174 {offsetof(struct acpi_battery, design_voltage), 0},
175 {offsetof(struct acpi_battery, design_capacity_warning), 0},
176 {offsetof(struct acpi_battery, design_capacity_low), 0},
177 {offsetof(struct acpi_battery, capacity_granularity_1), 0},
178 {offsetof(struct acpi_battery, capacity_granularity_2), 0},
179 {offsetof(struct acpi_battery, model_number), 1},
180 {offsetof(struct acpi_battery, serial_number), 1},
181 {offsetof(struct acpi_battery, type), 1},
182 {offsetof(struct acpi_battery, oem_info), 1},
185 static int extract_package(struct acpi_battery *battery,
186 union acpi_object *package,
187 struct acpi_offsets *offsets, int num)
190 union acpi_object *element;
191 if (package->type != ACPI_TYPE_PACKAGE)
193 for (i = 0; i < num; ++i) {
194 if (package->package.count <= i)
196 element = &package->package.elements[i];
197 if (offsets[i].mode) {
198 if (element->type != ACPI_TYPE_STRING &&
199 element->type != ACPI_TYPE_BUFFER)
201 strncpy((u8 *)battery + offsets[i].offset,
202 element->string.pointer, 32);
204 if (element->type != ACPI_TYPE_INTEGER)
206 x = (int *)((u8 *)battery + offsets[i].offset);
207 *x = element->integer.value;
213 static int acpi_battery_get_status(struct acpi_battery *battery)
217 result = acpi_bus_get_status(battery->device);
219 ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Evaluating _STA"));
225 static int acpi_battery_get_info(struct acpi_battery *battery)
228 acpi_status status = 0;
229 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
231 battery->update_time[ACPI_BATTERY_INFO] = get_seconds();
232 if (!acpi_battery_present(battery))
234 mutex_lock(&battery->lock);
235 status = acpi_evaluate_object(acpi_battery_handle(battery), "_BIF",
237 mutex_unlock(&battery->lock);
238 if (ACPI_FAILURE(status)) {
239 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF"));
242 result = extract_package(battery, buffer.pointer,
243 info_offsets, ARRAY_SIZE(info_offsets));
244 kfree(buffer.pointer);
248 static int acpi_battery_get_state(struct acpi_battery *battery)
251 acpi_status status = 0;
252 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
254 battery->update_time[ACPI_BATTERY_STATE] = get_seconds();
256 if (!acpi_battery_present(battery))
259 mutex_lock(&battery->lock);
260 status = acpi_evaluate_object(acpi_battery_handle(battery), "_BST",
262 mutex_unlock(&battery->lock);
264 if (ACPI_FAILURE(status)) {
265 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST"));
268 result = extract_package(battery, buffer.pointer,
269 state_offsets, ARRAY_SIZE(state_offsets));
270 kfree(buffer.pointer);
274 static int acpi_battery_get_alarm(struct acpi_battery *battery)
276 battery->update_time[ACPI_BATTERY_ALARM] = get_seconds();
281 static int acpi_battery_set_alarm(struct acpi_battery *battery,
284 acpi_status status = 0;
285 union acpi_object arg0 = { ACPI_TYPE_INTEGER };
286 struct acpi_object_list arg_list = { 1, &arg0 };
288 battery->update_time[ACPI_BATTERY_ALARM] = get_seconds();
290 if (!acpi_battery_present(battery))
293 if (!battery->alarm_present)
296 arg0.integer.value = alarm;
298 mutex_lock(&battery->lock);
299 status = acpi_evaluate_object(acpi_battery_handle(battery), "_BTP",
301 mutex_unlock(&battery->lock);
302 if (ACPI_FAILURE(status))
305 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Alarm set to %d\n", (u32) alarm));
307 battery->alarm = alarm;
312 static int acpi_battery_init_alarm(struct acpi_battery *battery)
315 acpi_status status = AE_OK;
316 acpi_handle handle = NULL;
317 unsigned long alarm = battery->alarm;
319 /* See if alarms are supported, and if so, set default */
321 status = acpi_get_handle(acpi_battery_handle(battery), "_BTP", &handle);
322 if (ACPI_SUCCESS(status)) {
323 battery->alarm_present = 1;
325 alarm = battery->design_capacity_warning;
327 result = acpi_battery_set_alarm(battery, alarm);
331 battery->alarm_present = 0;
339 static int acpi_battery_init_update(struct acpi_battery *battery)
343 result = acpi_battery_get_status(battery);
347 battery->present_prev = acpi_battery_present(battery);
349 if (acpi_battery_present(battery)) {
350 result = acpi_battery_get_info(battery);
353 result = acpi_battery_get_state(battery);
357 acpi_battery_init_alarm(battery);
363 static int acpi_battery_update(struct acpi_battery *battery,
364 int update, int *update_result_ptr)
367 int update_result = ACPI_BATTERY_NONE_UPDATE;
369 if (!acpi_battery_present(battery)) {
373 if (battery->init_update) {
374 result = acpi_battery_init_update(battery);
377 update_result = ACPI_BATTERY_INIT_UPDATE;
379 result = acpi_battery_get_status(battery);
382 if ((!battery->present_prev & acpi_battery_present(battery))
383 || (battery->present_prev & !acpi_battery_present(battery))) {
384 result = acpi_battery_init_update(battery);
387 update_result = ACPI_BATTERY_INIT_UPDATE;
389 update_result = ACPI_BATTERY_EASY_UPDATE;
395 battery->init_update = (result != 0);
397 *update_result_ptr = update_result;
402 static void acpi_battery_notify_update(struct acpi_battery *battery)
404 acpi_battery_get_status(battery);
406 if (battery->init_update) {
410 if ((!battery->present_prev &
411 acpi_battery_present(battery)) ||
412 (battery->present_prev &
413 !acpi_battery_present(battery))) {
414 battery->init_update = 1;
416 battery->update[ACPI_BATTERY_INFO] = 1;
417 battery->update[ACPI_BATTERY_STATE] = 1;
418 battery->update[ACPI_BATTERY_ALARM] = 1;
422 /* --------------------------------------------------------------------------
424 -------------------------------------------------------------------------- */
426 static struct proc_dir_entry *acpi_battery_dir;
428 static int acpi_battery_print_info(struct seq_file *seq, int result)
430 struct acpi_battery *battery = seq->private;
436 if (acpi_battery_present(battery))
437 seq_printf(seq, "present: yes\n");
439 seq_printf(seq, "present: no\n");
445 units = acpi_battery_power_units(battery);
447 if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
448 seq_printf(seq, "design capacity: unknown\n");
450 seq_printf(seq, "design capacity: %d %sh\n",
451 (u32) battery->design_capacity, units);
453 if (battery->last_full_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
454 seq_printf(seq, "last full capacity: unknown\n");
456 seq_printf(seq, "last full capacity: %d %sh\n",
457 (u32) battery->last_full_capacity, units);
459 switch ((u32) battery->technology) {
461 seq_printf(seq, "battery technology: non-rechargeable\n");
464 seq_printf(seq, "battery technology: rechargeable\n");
467 seq_printf(seq, "battery technology: unknown\n");
471 if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
472 seq_printf(seq, "design voltage: unknown\n");
474 seq_printf(seq, "design voltage: %d mV\n",
475 (u32) battery->design_voltage);
476 seq_printf(seq, "design capacity warning: %d %sh\n",
477 (u32) battery->design_capacity_warning, units);
478 seq_printf(seq, "design capacity low: %d %sh\n",
479 (u32) battery->design_capacity_low, units);
480 seq_printf(seq, "capacity granularity 1: %d %sh\n",
481 (u32) battery->capacity_granularity_1, units);
482 seq_printf(seq, "capacity granularity 2: %d %sh\n",
483 (u32) battery->capacity_granularity_2, units);
484 seq_printf(seq, "model number: %s\n", battery->model_number);
485 seq_printf(seq, "serial number: %s\n", battery->serial_number);
486 seq_printf(seq, "battery type: %s\n", battery->type);
487 seq_printf(seq, "OEM info: %s\n", battery->oem_info);
492 seq_printf(seq, "ERROR: Unable to read battery info\n");
497 static int acpi_battery_print_state(struct seq_file *seq, int result)
499 struct acpi_battery *battery = seq->private;
505 if (acpi_battery_present(battery))
506 seq_printf(seq, "present: yes\n");
508 seq_printf(seq, "present: no\n");
514 units = acpi_battery_power_units(battery);
516 if (!(battery->state & 0x04))
517 seq_printf(seq, "capacity state: ok\n");
519 seq_printf(seq, "capacity state: critical\n");
521 if ((battery->state & 0x01) && (battery->state & 0x02)) {
523 "charging state: charging/discharging\n");
524 } else if (battery->state & 0x01)
525 seq_printf(seq, "charging state: discharging\n");
526 else if (battery->state & 0x02)
527 seq_printf(seq, "charging state: charging\n");
529 seq_printf(seq, "charging state: charged\n");
532 if (battery->present_rate == ACPI_BATTERY_VALUE_UNKNOWN)
533 seq_printf(seq, "present rate: unknown\n");
535 seq_printf(seq, "present rate: %d %s\n",
536 (u32) battery->present_rate, units);
538 if (battery->remaining_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
539 seq_printf(seq, "remaining capacity: unknown\n");
541 seq_printf(seq, "remaining capacity: %d %sh\n",
542 (u32) battery->remaining_capacity, units);
544 if (battery->present_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
545 seq_printf(seq, "present voltage: unknown\n");
547 seq_printf(seq, "present voltage: %d mV\n",
548 (u32) battery->present_voltage);
553 seq_printf(seq, "ERROR: Unable to read battery state\n");
559 static int acpi_battery_print_alarm(struct seq_file *seq, int result)
561 struct acpi_battery *battery = seq->private;
567 if (!acpi_battery_present(battery)) {
568 seq_printf(seq, "present: no\n");
574 units = acpi_battery_power_units(battery);
576 seq_printf(seq, "alarm: ");
578 seq_printf(seq, "unsupported\n");
580 seq_printf(seq, "%lu %sh\n", battery->alarm, units);
585 seq_printf(seq, "ERROR: Unable to read battery alarm\n");
591 acpi_battery_write_alarm(struct file *file,
592 const char __user * buffer,
593 size_t count, loff_t * ppos)
596 char alarm_string[12] = { '\0' };
597 struct seq_file *m = file->private_data;
598 struct acpi_battery *battery = m->private;
599 int update_result = ACPI_BATTERY_NONE_UPDATE;
601 if (!battery || (count > sizeof(alarm_string) - 1))
604 result = acpi_battery_update(battery, 1, &update_result);
610 if (!acpi_battery_present(battery)) {
615 if (copy_from_user(alarm_string, buffer, count)) {
620 alarm_string[count] = '\0';
622 result = acpi_battery_set_alarm(battery,
623 simple_strtoul(alarm_string, NULL, 0));
629 acpi_battery_check_result(battery, result);
636 typedef int(*print_func)(struct seq_file *seq, int result);
637 typedef int(*get_func)(struct acpi_battery *battery);
639 static struct acpi_read_mux {
642 } acpi_read_funcs[ACPI_BATTERY_NUMFILES] = {
643 {.get = acpi_battery_get_info, .print = acpi_battery_print_info},
644 {.get = acpi_battery_get_state, .print = acpi_battery_print_state},
645 {.get = acpi_battery_get_alarm, .print = acpi_battery_print_alarm},
648 static int acpi_battery_read(int fid, struct seq_file *seq)
650 struct acpi_battery *battery = seq->private;
652 int update_result = ACPI_BATTERY_NONE_UPDATE;
655 update = (get_seconds() - battery->update_time[fid] >= update_time);
656 update = (update | battery->update[fid]);
658 result = acpi_battery_update(battery, update, &update_result);
662 if (update_result == ACPI_BATTERY_EASY_UPDATE) {
663 result = acpi_read_funcs[fid].get(battery);
669 result = acpi_read_funcs[fid].print(seq, result);
670 acpi_battery_check_result(battery, result);
671 battery->update[fid] = result;
675 static int acpi_battery_read_info(struct seq_file *seq, void *offset)
677 return acpi_battery_read(ACPI_BATTERY_INFO, seq);
680 static int acpi_battery_read_state(struct seq_file *seq, void *offset)
682 return acpi_battery_read(ACPI_BATTERY_STATE, seq);
685 static int acpi_battery_read_alarm(struct seq_file *seq, void *offset)
687 return acpi_battery_read(ACPI_BATTERY_ALARM, seq);
690 static int acpi_battery_info_open_fs(struct inode *inode, struct file *file)
692 return single_open(file, acpi_battery_read_info, PDE(inode)->data);
695 static int acpi_battery_state_open_fs(struct inode *inode, struct file *file)
697 return single_open(file, acpi_battery_read_state, PDE(inode)->data);
700 static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file)
702 return single_open(file, acpi_battery_read_alarm, PDE(inode)->data);
705 static struct battery_file {
706 struct file_operations ops;
709 } acpi_battery_file[] = {
714 .open = acpi_battery_info_open_fs,
717 .release = single_release,
718 .owner = THIS_MODULE,
725 .open = acpi_battery_state_open_fs,
728 .release = single_release,
729 .owner = THIS_MODULE,
734 .mode = S_IFREG | S_IRUGO | S_IWUSR,
736 .open = acpi_battery_alarm_open_fs,
738 .write = acpi_battery_write_alarm,
740 .release = single_release,
741 .owner = THIS_MODULE,
746 static int acpi_battery_add_fs(struct acpi_device *device)
748 struct proc_dir_entry *entry = NULL;
751 if (!acpi_device_dir(device)) {
752 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
754 if (!acpi_device_dir(device))
756 acpi_device_dir(device)->owner = THIS_MODULE;
759 for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) {
760 entry = create_proc_entry(acpi_battery_file[i].name,
761 acpi_battery_file[i].mode, acpi_device_dir(device));
765 entry->proc_fops = &acpi_battery_file[i].ops;
766 entry->data = acpi_driver_data(device);
767 entry->owner = THIS_MODULE;
774 static int acpi_battery_remove_fs(struct acpi_device *device)
777 if (acpi_device_dir(device)) {
778 for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) {
779 remove_proc_entry(acpi_battery_file[i].name,
780 acpi_device_dir(device));
782 remove_proc_entry(acpi_device_bid(device), acpi_battery_dir);
783 acpi_device_dir(device) = NULL;
789 /* --------------------------------------------------------------------------
791 -------------------------------------------------------------------------- */
793 static void acpi_battery_notify(acpi_handle handle, u32 event, void *data)
795 struct acpi_battery *battery = data;
796 struct acpi_device *device = NULL;
801 device = battery->device;
804 case ACPI_BATTERY_NOTIFY_STATUS:
805 case ACPI_BATTERY_NOTIFY_INFO:
806 case ACPI_NOTIFY_BUS_CHECK:
807 case ACPI_NOTIFY_DEVICE_CHECK:
808 device = battery->device;
809 acpi_battery_notify_update(battery);
810 acpi_bus_generate_proc_event(device, event,
811 acpi_battery_present(battery));
812 acpi_bus_generate_netlink_event(device->pnp.device_class,
813 device->dev.bus_id, event,
814 acpi_battery_present(battery));
817 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
818 "Unsupported event [0x%x]\n", event));
825 static int acpi_battery_add(struct acpi_device *device)
828 acpi_status status = 0;
829 struct acpi_battery *battery = NULL;
834 battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL);
838 battery->device = device;
839 strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME);
840 strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS);
841 acpi_driver_data(device) = battery;
842 mutex_init(&battery->lock);
843 result = acpi_battery_get_status(battery);
847 battery->init_update = 1;
849 result = acpi_battery_add_fs(device);
853 status = acpi_install_notify_handler(device->handle,
855 acpi_battery_notify, battery);
856 if (ACPI_FAILURE(status)) {
857 ACPI_EXCEPTION((AE_INFO, status, "Installing notify handler"));
862 printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n",
863 ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device),
864 device->status.battery_present ? "present" : "absent");
869 acpi_battery_remove_fs(device);
876 static int acpi_battery_remove(struct acpi_device *device, int type)
878 acpi_status status = 0;
879 struct acpi_battery *battery = NULL;
881 if (!device || !acpi_driver_data(device))
884 battery = acpi_driver_data(device);
886 status = acpi_remove_notify_handler(device->handle,
888 acpi_battery_notify);
890 acpi_battery_remove_fs(device);
891 mutex_destroy(&battery->lock);
897 /* this is needed to learn about changes made in suspended state */
898 static int acpi_battery_resume(struct acpi_device *device)
900 struct acpi_battery *battery;
905 battery = device->driver_data;
907 battery->init_update = 1;
912 static int __init acpi_battery_init(void)
919 acpi_battery_dir = acpi_lock_battery_dir();
920 if (!acpi_battery_dir)
923 result = acpi_bus_register_driver(&acpi_battery_driver);
925 acpi_unlock_battery_dir(acpi_battery_dir);
932 static void __exit acpi_battery_exit(void)
934 acpi_bus_unregister_driver(&acpi_battery_driver);
936 acpi_unlock_battery_dir(acpi_battery_dir);
941 module_init(acpi_battery_init);
942 module_exit(acpi_battery_exit);