2 * acpi_sbs.c - ACPI Smart Battery System Driver ($Revision: 1.16 $)
4 * Copyright (c) 2005 Rich Townsend <rhdt@bartol.udel.edu>
6 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or (at
11 * your option) any later version.
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
22 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25 #include <linux/init.h>
26 #include <linux/module.h>
27 #include <linux/moduleparam.h>
28 #include <linux/kernel.h>
29 #include <linux/proc_fs.h>
30 #include <linux/seq_file.h>
31 #include <asm/uaccess.h>
32 #include <linux/acpi.h>
33 #include <linux/timer.h>
34 #include <linux/jiffies.h>
35 #include <linux/delay.h>
39 #define ACPI_SBS_COMPONENT 0x00080000
40 #define ACPI_SBS_CLASS "sbs"
41 #define ACPI_AC_CLASS "ac_adapter"
42 #define ACPI_BATTERY_CLASS "battery"
43 #define ACPI_SBS_DEVICE_NAME "Smart Battery System"
44 #define ACPI_SBS_FILE_INFO "info"
45 #define ACPI_SBS_FILE_STATE "state"
46 #define ACPI_SBS_FILE_ALARM "alarm"
47 #define ACPI_BATTERY_DIR_NAME "BAT%i"
48 #define ACPI_AC_DIR_NAME "AC0"
49 #define ACPI_SBC_SMBUS_ADDR 0x9
50 #define ACPI_SBSM_SMBUS_ADDR 0xa
51 #define ACPI_SB_SMBUS_ADDR 0xb
52 #define ACPI_SBS_AC_NOTIFY_STATUS 0x80
53 #define ACPI_SBS_BATTERY_NOTIFY_STATUS 0x80
54 #define ACPI_SBS_BATTERY_NOTIFY_INFO 0x81
56 #define _COMPONENT ACPI_SBS_COMPONENT
58 ACPI_MODULE_NAME("sbs");
60 MODULE_AUTHOR("Rich Townsend");
61 MODULE_DESCRIPTION("Smart Battery System ACPI interface driver");
62 MODULE_LICENSE("GPL");
64 #define DEF_CAPACITY_UNIT 3
65 #define MAH_CAPACITY_UNIT 1
66 #define MWH_CAPACITY_UNIT 2
67 #define CAPACITY_UNIT DEF_CAPACITY_UNIT
69 #define REQUEST_UPDATE_MODE 1
70 #define QUEUE_UPDATE_MODE 2
72 #define DATA_TYPE_COMMON 0
73 #define DATA_TYPE_INFO 1
74 #define DATA_TYPE_STATE 2
75 #define DATA_TYPE_ALARM 3
76 #define DATA_TYPE_AC_STATE 4
78 extern struct proc_dir_entry *acpi_lock_ac_dir(void);
79 extern struct proc_dir_entry *acpi_lock_battery_dir(void);
80 extern void acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir);
81 extern void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
84 #define ACPI_SBS_BLOCK_MAX 32
86 #define UPDATE_DELAY 10
88 /* 0 - every time, > 0 - by update_time */
89 static unsigned int update_time = 120;
91 static unsigned int mode = CAPACITY_UNIT;
93 module_param(update_time, uint, 0644);
94 module_param(mode, uint, 0444);
96 static int acpi_sbs_add(struct acpi_device *device);
97 static int acpi_sbs_remove(struct acpi_device *device, int type);
98 static int acpi_sbs_resume(struct acpi_device *device);
100 static const struct acpi_device_id sbs_device_ids[] = {
104 MODULE_DEVICE_TABLE(acpi, sbs_device_ids);
106 static struct acpi_driver acpi_sbs_driver = {
108 .class = ACPI_SBS_CLASS,
109 .ids = sbs_device_ids,
112 .remove = acpi_sbs_remove,
113 .resume = acpi_sbs_resume,
117 struct acpi_battery {
118 struct acpi_sbs *sbs;
119 struct proc_dir_entry *proc_entry;
122 char manufacturer_name[ACPI_SBS_BLOCK_MAX];
123 char device_name[ACPI_SBS_BLOCK_MAX];
124 char device_chemistry[ACPI_SBS_BLOCK_MAX];
125 u16 full_charge_capacity;
142 struct acpi_device *device;
143 struct acpi_smb_hc *hc;
145 struct proc_dir_entry *ac_entry;
146 struct acpi_battery battery[MAX_SBS_BAT];
148 struct timer_list update_timer;
151 u8 batteries_supported;
152 u8 manager_present:1;
153 u8 charger_present:1;
156 static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type);
157 static void acpi_sbs_update_time(void *data);
159 static int sbs_zombie(struct acpi_sbs *sbs)
161 return (sbs->zombie);
164 static int sbs_mutex_lock(struct acpi_sbs *sbs)
166 if (sbs_zombie(sbs)) {
169 mutex_lock(&sbs->mutex);
173 static void sbs_mutex_unlock(struct acpi_sbs *sbs)
175 mutex_unlock(&sbs->mutex);
178 /* --------------------------------------------------------------------------
179 Smart Battery System Management
180 -------------------------------------------------------------------------- */
182 static int acpi_check_update_proc(struct acpi_sbs *sbs)
184 acpi_status status = AE_OK;
186 if (update_time == 0) {
187 sbs->update_proc_flg = 0;
190 if (sbs->update_proc_flg == 0) {
191 status = acpi_os_execute(OSL_GPE_HANDLER,
192 acpi_sbs_update_time, sbs);
193 if (status != AE_OK) {
194 ACPI_EXCEPTION((AE_INFO, status,
195 "acpi_os_execute() failed"));
198 sbs->update_proc_flg = 1;
203 static int acpi_battery_get_present(struct acpi_battery *battery)
209 result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD,
210 ACPI_SBSM_SMBUS_ADDR, 0x01, (u8 *)&state);
212 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
213 "acpi_smbus_read() failed"));
216 is_present = (state & 0x000f) & (1 << battery->id);
218 battery->present = is_present;
223 static int acpi_battery_select(struct acpi_battery *battery)
225 struct acpi_sbs *sbs = battery->sbs;
230 if (sbs->manager_present) {
232 /* Take special care not to knobble other nibbles of
233 * state (aka selector_state), since
234 * it causes charging to halt on SBSELs */
236 result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD,
237 ACPI_SBSM_SMBUS_ADDR, 0x01, (u8 *)&state);
239 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
240 "acpi_smbus_read() failed"));
244 foo = (state & 0x0fff) | (1 << (battery->id + 12));
245 result = acpi_smbus_write(battery->sbs->hc, SMBUS_WRITE_WORD,
246 ACPI_SBSM_SMBUS_ADDR, 0x01, (u8 *)&foo, 2);
248 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
249 "acpi_smbus_write() failed"));
258 static int acpi_sbsm_get_info(struct acpi_sbs *sbs)
261 s16 battery_system_info;
263 result = acpi_smbus_read(sbs->hc, SMBUS_READ_WORD, ACPI_SBSM_SMBUS_ADDR, 0x04,
264 (u8 *)&battery_system_info);
266 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
267 "acpi_smbus_read() failed"));
270 sbs->manager_present = 1;
277 static int acpi_battery_get_info(struct acpi_battery *battery)
281 s16 specification_info;
283 result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x03,
284 (u8 *)&battery_mode);
286 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
287 "acpi_smbus_read() failed"));
290 battery->mode = (battery_mode & 0x8000) >> 15;
292 result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x10,
293 (u8 *)&battery->full_charge_capacity);
295 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
296 "acpi_smbus_read() failed"));
300 result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x18,
301 (u8 *)&battery->design_capacity);
304 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
305 "acpi_smbus_read() failed"));
309 result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x19,
310 (u8 *)&battery->design_voltage);
312 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
313 "acpi_smbus_read() failed"));
317 result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x1a,
318 (u8 *)&specification_info);
320 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
321 "acpi_smbus_read() failed"));
325 switch ((specification_info & 0x0f00) >> 8) {
327 battery->vscale = 10;
330 battery->vscale = 100;
333 battery->vscale = 1000;
339 switch ((specification_info & 0xf000) >> 12) {
341 battery->ipscale = 10;
344 battery->ipscale = 100;
347 battery->ipscale = 1000;
350 battery->ipscale = 1;
353 result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x1c,
354 (u8 *)&battery->serial_number);
356 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
357 "acpi_smbus_read() failed"));
361 result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_BLOCK, ACPI_SB_SMBUS_ADDR, 0x20,
362 (u8 *)battery->manufacturer_name);
364 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
365 "acpi_sbs_read_str() failed"));
369 result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_BLOCK, ACPI_SB_SMBUS_ADDR, 0x21,
370 (u8 *)battery->device_name);
372 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
373 "acpi_sbs_read_str() failed"));
377 result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_BLOCK, ACPI_SB_SMBUS_ADDR, 0x22,
378 (u8 *)battery->device_chemistry);
380 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
381 "acpi_sbs_read_str() failed"));
389 static int acpi_battery_get_state(struct acpi_battery *battery)
393 result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x09,
394 (u8 *)&battery->voltage_now);
396 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
397 "acpi_smbus_read() failed"));
401 result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x0a,
402 (u8 *)&battery->current_now);
404 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
405 "acpi_smbus_read() failed"));
409 result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x0f,
410 (u8 *)&battery->capacity_now);
412 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
413 "acpi_smbus_read() failed"));
417 result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x16,
418 (u8 *)&battery->state);
420 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
421 "acpi_smbus_read() failed"));
429 static int acpi_battery_get_alarm(struct acpi_battery *battery)
433 result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x01,
434 (u8 *)&battery->alarm_capacity);
436 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
437 "acpi_smbus_read() failed"));
446 static int acpi_battery_set_alarm(struct acpi_battery *battery,
453 result = acpi_battery_select(battery);
455 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
456 "acpi_battery_select() failed"));
460 /* If necessary, enable the alarm */
464 acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x03,
465 (u8 *)&battery_mode);
467 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
468 "acpi_smbus_read() failed"));
472 battery_mode &= 0xbfff;
474 acpi_smbus_write(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x01,
475 (u8 *)&battery_mode, 2);
477 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
478 "acpi_smbus_write() failed"));
483 foo = alarm / (battery->mode ? 10 : 1);
484 result = acpi_smbus_write(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x01,
487 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
488 "acpi_smbus_write() failed"));
497 static int acpi_battery_set_mode(struct acpi_battery *battery)
502 if (mode == DEF_CAPACITY_UNIT) {
506 result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD,
507 ACPI_SB_SMBUS_ADDR, 0x03, (u8 *)&battery_mode);
509 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
510 "acpi_smbus_read() failed"));
514 if (mode == MAH_CAPACITY_UNIT) {
515 battery_mode &= 0x7fff;
517 battery_mode |= 0x8000;
519 result = acpi_smbus_write(battery->sbs->hc, SMBUS_READ_WORD,
520 ACPI_SB_SMBUS_ADDR, 0x03, (u8 *)&battery_mode, 2);
522 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
523 "acpi_smbus_write() failed"));
527 result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD,
528 ACPI_SB_SMBUS_ADDR, 0x03, (u8 *)&battery_mode);
530 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
531 "acpi_smbus_read() failed"));
539 static int acpi_battery_init(struct acpi_battery *battery)
543 result = acpi_battery_select(battery);
545 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
546 "acpi_battery_select() failed"));
550 result = acpi_battery_set_mode(battery);
552 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
553 "acpi_battery_set_mode() failed"));
557 result = acpi_battery_get_info(battery);
559 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
560 "acpi_battery_get_info() failed"));
564 result = acpi_battery_get_state(battery);
566 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
567 "acpi_battery_get_state() failed"));
571 result = acpi_battery_get_alarm(battery);
573 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
574 "acpi_battery_get_alarm() failed"));
582 static int acpi_ac_get_present(struct acpi_sbs *sbs)
587 result = acpi_smbus_read(sbs->hc, SMBUS_READ_WORD, ACPI_SBC_SMBUS_ADDR, 0x13,
588 (u8 *)&charger_status);
591 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
592 "acpi_smbus_read() failed"));
596 sbs->charger_present = (charger_status & 0x8000) >> 15;
603 /* --------------------------------------------------------------------------
604 FS Interface (/proc/acpi)
605 -------------------------------------------------------------------------- */
607 /* Generic Routines */
610 acpi_sbs_generic_add_fs(struct proc_dir_entry **dir,
611 struct proc_dir_entry *parent_dir,
613 struct file_operations *info_fops,
614 struct file_operations *state_fops,
615 struct file_operations *alarm_fops, void *data)
617 struct proc_dir_entry *entry = NULL;
620 *dir = proc_mkdir(dir_name, parent_dir);
622 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
623 "proc_mkdir() failed"));
626 (*dir)->owner = THIS_MODULE;
631 entry = create_proc_entry(ACPI_SBS_FILE_INFO, S_IRUGO, *dir);
633 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
634 "create_proc_entry() failed"));
636 entry->proc_fops = info_fops;
638 entry->owner = THIS_MODULE;
644 entry = create_proc_entry(ACPI_SBS_FILE_STATE, S_IRUGO, *dir);
646 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
647 "create_proc_entry() failed"));
649 entry->proc_fops = state_fops;
651 entry->owner = THIS_MODULE;
657 entry = create_proc_entry(ACPI_SBS_FILE_ALARM, S_IRUGO, *dir);
659 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
660 "create_proc_entry() failed"));
662 entry->proc_fops = alarm_fops;
664 entry->owner = THIS_MODULE;
672 acpi_sbs_generic_remove_fs(struct proc_dir_entry **dir,
673 struct proc_dir_entry *parent_dir)
677 remove_proc_entry(ACPI_SBS_FILE_INFO, *dir);
678 remove_proc_entry(ACPI_SBS_FILE_STATE, *dir);
679 remove_proc_entry(ACPI_SBS_FILE_ALARM, *dir);
680 remove_proc_entry((*dir)->name, parent_dir);
686 /* Smart Battery Interface */
688 static struct proc_dir_entry *acpi_battery_dir = NULL;
690 static int acpi_battery_read_info(struct seq_file *seq, void *offset)
692 struct acpi_battery *battery = seq->private;
693 struct acpi_sbs *sbs = battery->sbs;
697 if (sbs_mutex_lock(sbs)) {
701 result = acpi_check_update_proc(sbs);
705 if (update_time == 0) {
706 result = acpi_sbs_update_run(sbs, battery->id, DATA_TYPE_INFO);
708 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
709 "acpi_sbs_update_run() failed"));
713 if (battery->present) {
714 seq_printf(seq, "present: yes\n");
716 seq_printf(seq, "present: no\n");
721 cscale = battery->vscale * battery->ipscale;
723 cscale = battery->ipscale;
725 seq_printf(seq, "design capacity: %i%s\n",
726 battery->design_capacity * cscale,
727 battery->mode ? "0 mWh" : " mAh");
729 seq_printf(seq, "last full capacity: %i%s\n",
730 battery->full_charge_capacity * cscale,
731 battery->mode ? "0 mWh" : " mAh");
733 seq_printf(seq, "battery technology: rechargeable\n");
735 seq_printf(seq, "design voltage: %i mV\n",
736 battery->design_voltage * battery->vscale);
738 seq_printf(seq, "design capacity warning: unknown\n");
739 seq_printf(seq, "design capacity low: unknown\n");
740 seq_printf(seq, "capacity granularity 1: unknown\n");
741 seq_printf(seq, "capacity granularity 2: unknown\n");
743 seq_printf(seq, "model number: %s\n",
744 battery->device_name);
746 seq_printf(seq, "serial number: %i\n",
747 battery->serial_number);
749 seq_printf(seq, "battery type: %s\n",
750 battery->device_chemistry);
752 seq_printf(seq, "OEM info: %s\n",
753 battery->manufacturer_name);
757 sbs_mutex_unlock(sbs);
762 static int acpi_battery_info_open_fs(struct inode *inode, struct file *file)
764 return single_open(file, acpi_battery_read_info, PDE(inode)->data);
767 static int acpi_battery_read_state(struct seq_file *seq, void *offset)
769 struct acpi_battery *battery = seq->private;
770 struct acpi_sbs *sbs = battery->sbs;
775 if (sbs_mutex_lock(sbs)) {
779 result = acpi_check_update_proc(sbs);
783 if (update_time == 0) {
784 result = acpi_sbs_update_run(sbs, battery->id, DATA_TYPE_STATE);
786 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
787 "acpi_sbs_update_run() failed"));
791 if (battery->present) {
792 seq_printf(seq, "present: yes\n");
794 seq_printf(seq, "present: no\n");
799 cscale = battery->vscale * battery->ipscale;
801 cscale = battery->ipscale;
804 if (battery->state & 0x0010) {
805 seq_printf(seq, "capacity state: critical\n");
807 seq_printf(seq, "capacity state: ok\n");
810 foo = (s16) battery->current_now * battery->ipscale;
812 foo = foo * battery->design_voltage / 1000;
814 if (battery->current_now < 0) {
815 seq_printf(seq, "charging state: discharging\n");
816 seq_printf(seq, "present rate: %d %s\n",
817 -foo, battery->mode ? "mW" : "mA");
818 } else if (battery->current_now > 0) {
819 seq_printf(seq, "charging state: charging\n");
820 seq_printf(seq, "present rate: %d %s\n",
821 foo, battery->mode ? "mW" : "mA");
823 seq_printf(seq, "charging state: charged\n");
824 seq_printf(seq, "present rate: 0 %s\n",
825 battery->mode ? "mW" : "mA");
828 seq_printf(seq, "remaining capacity: %i%s\n",
829 battery->capacity_now * cscale,
830 battery->mode ? "0 mWh" : " mAh");
832 seq_printf(seq, "present voltage: %i mV\n",
833 battery->voltage_now * battery->vscale);
837 sbs_mutex_unlock(sbs);
842 static int acpi_battery_state_open_fs(struct inode *inode, struct file *file)
844 return single_open(file, acpi_battery_read_state, PDE(inode)->data);
847 static int acpi_battery_read_alarm(struct seq_file *seq, void *offset)
849 struct acpi_battery *battery = seq->private;
850 struct acpi_sbs *sbs = battery->sbs;
854 if (sbs_mutex_lock(sbs)) {
858 result = acpi_check_update_proc(sbs);
862 if (update_time == 0) {
863 result = acpi_sbs_update_run(sbs, battery->id, DATA_TYPE_ALARM);
865 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
866 "acpi_sbs_update_run() failed"));
870 if (!battery->present) {
871 seq_printf(seq, "present: no\n");
876 cscale = battery->vscale * battery->ipscale;
878 cscale = battery->ipscale;
881 seq_printf(seq, "alarm: ");
882 if (battery->alarm_capacity) {
883 seq_printf(seq, "%i%s\n",
884 battery->alarm_capacity * cscale,
885 battery->mode ? "0 mWh" : " mAh");
887 seq_printf(seq, "disabled\n");
892 sbs_mutex_unlock(sbs);
898 acpi_battery_write_alarm(struct file *file, const char __user * buffer,
899 size_t count, loff_t * ppos)
901 struct seq_file *seq = file->private_data;
902 struct acpi_battery *battery = seq->private;
903 struct acpi_sbs *sbs = battery->sbs;
904 char alarm_string[12] = { '\0' };
905 int result, old_alarm, new_alarm;
907 if (sbs_mutex_lock(sbs)) {
911 result = acpi_check_update_proc(sbs);
915 if (!battery->present) {
920 if (count > sizeof(alarm_string) - 1) {
925 if (copy_from_user(alarm_string, buffer, count)) {
930 alarm_string[count] = 0;
932 old_alarm = battery->alarm_capacity;
933 new_alarm = simple_strtoul(alarm_string, NULL, 0);
935 result = acpi_battery_set_alarm(battery, new_alarm);
937 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
938 "acpi_battery_set_alarm() failed"));
939 acpi_battery_set_alarm(battery, old_alarm);
942 result = acpi_battery_get_alarm(battery);
944 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
945 "acpi_battery_get_alarm() failed"));
946 acpi_battery_set_alarm(battery, old_alarm);
951 sbs_mutex_unlock(sbs);
960 static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file)
962 return single_open(file, acpi_battery_read_alarm, PDE(inode)->data);
965 static struct file_operations acpi_battery_info_fops = {
966 .open = acpi_battery_info_open_fs,
969 .release = single_release,
970 .owner = THIS_MODULE,
973 static struct file_operations acpi_battery_state_fops = {
974 .open = acpi_battery_state_open_fs,
977 .release = single_release,
978 .owner = THIS_MODULE,
981 static struct file_operations acpi_battery_alarm_fops = {
982 .open = acpi_battery_alarm_open_fs,
984 .write = acpi_battery_write_alarm,
986 .release = single_release,
987 .owner = THIS_MODULE,
990 /* Legacy AC Adapter Interface */
992 static struct proc_dir_entry *acpi_ac_dir = NULL;
994 static int acpi_ac_read_state(struct seq_file *seq, void *offset)
996 struct acpi_sbs *sbs = seq->private;
999 if (sbs_mutex_lock(sbs)) {
1003 if (update_time == 0) {
1004 result = acpi_sbs_update_run(sbs, -1, DATA_TYPE_AC_STATE);
1006 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1007 "acpi_sbs_update_run() failed"));
1011 seq_printf(seq, "state: %s\n",
1012 sbs->charger_present ? "on-line" : "off-line");
1014 sbs_mutex_unlock(sbs);
1019 static int acpi_ac_state_open_fs(struct inode *inode, struct file *file)
1021 return single_open(file, acpi_ac_read_state, PDE(inode)->data);
1024 static struct file_operations acpi_ac_state_fops = {
1025 .open = acpi_ac_state_open_fs,
1027 .llseek = seq_lseek,
1028 .release = single_release,
1029 .owner = THIS_MODULE,
1032 /* --------------------------------------------------------------------------
1034 -------------------------------------------------------------------------- */
1038 static int acpi_battery_add(struct acpi_sbs *sbs, int id)
1043 struct acpi_battery *battery;
1045 battery = &sbs->battery[id];
1049 battery->init_state = 0;
1053 result = acpi_battery_select(battery);
1055 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1056 "acpi_battery_select() failed"));
1060 result = acpi_battery_get_present(battery);
1062 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1063 "acpi_battery_get_present() failed"));
1067 is_present = battery->present;
1070 result = acpi_battery_init(battery);
1072 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1073 "acpi_battery_init() failed"));
1076 battery->init_state = 1;
1079 sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id);
1081 result = acpi_sbs_generic_add_fs(&battery->proc_entry,
1084 &acpi_battery_info_fops,
1085 &acpi_battery_state_fops,
1086 &acpi_battery_alarm_fops, battery);
1088 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1089 "acpi_sbs_generic_add_fs() failed"));
1094 printk(KERN_INFO PREFIX "%s [%s]: Battery Slot [%s] (battery %s)\n",
1095 ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device), dir_name,
1096 sbs->battery->present ? "present" : "absent");
1102 static void acpi_battery_remove(struct acpi_sbs *sbs, int id)
1105 if (sbs->battery[id].proc_entry) {
1106 acpi_sbs_generic_remove_fs(&(sbs->battery[id].proc_entry),
1111 static int acpi_ac_add(struct acpi_sbs *sbs)
1115 result = acpi_ac_get_present(sbs);
1117 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1118 "acpi_ac_get_present() failed"));
1122 result = acpi_sbs_generic_add_fs(&sbs->ac_entry,
1125 NULL, &acpi_ac_state_fops, NULL, sbs);
1127 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1128 "acpi_sbs_generic_add_fs() failed"));
1132 printk(KERN_INFO PREFIX "%s [%s]: AC Adapter [%s] (%s)\n",
1133 ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device),
1134 ACPI_AC_DIR_NAME, sbs->charger_present ? "on-line" : "off-line");
1141 static void acpi_ac_remove(struct acpi_sbs *sbs)
1144 if (sbs->ac_entry) {
1145 acpi_sbs_generic_remove_fs(&sbs->ac_entry, acpi_ac_dir);
1149 static void acpi_sbs_update_time_run(unsigned long data)
1151 acpi_os_execute(OSL_GPE_HANDLER, acpi_sbs_update_time, (void *)data);
1154 static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type)
1156 struct acpi_battery *battery;
1157 int result = 0, cnt;
1158 int old_ac_present = -1;
1159 int old_present = -1;
1160 int new_ac_present = -1;
1161 int new_present = -1;
1162 int id_min = 0, id_max = MAX_SBS_BAT - 1;
1164 int do_battery_init = 0, do_ac_init = 0;
1165 int old_remaining_capacity = 0;
1166 int update_battery = 1;
1167 int up_tm = update_time;
1169 if (sbs_zombie(sbs)) {
1174 id_min = id_max = id;
1177 if (data_type == DATA_TYPE_COMMON && up_tm > 0) {
1178 cnt = up_tm / (up_tm > UPDATE_DELAY ? UPDATE_DELAY : up_tm);
1179 if (sbs->run_cnt % cnt != 0) {
1186 if (!update_battery) {
1190 old_ac_present = sbs->charger_present;
1192 result = acpi_ac_get_present(sbs);
1194 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1195 "acpi_ac_get_present() failed"));
1198 new_ac_present = sbs->charger_present;
1200 do_ac_init = (old_ac_present != new_ac_present);
1201 if (sbs->run_cnt == 1 && data_type == DATA_TYPE_COMMON) {
1206 result = acpi_bus_generate_proc_event4(ACPI_AC_CLASS,
1208 ACPI_SBS_AC_NOTIFY_STATUS,
1211 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1212 "acpi_bus_generate_event4() failed"));
1214 acpi_bus_generate_netlink_event(ACPI_AC_CLASS, ACPI_AC_DIR_NAME,
1215 ACPI_SBS_AC_NOTIFY_STATUS,
1219 if (data_type == DATA_TYPE_COMMON) {
1220 if (!do_ac_init && !update_battery) {
1225 if (data_type == DATA_TYPE_AC_STATE && !do_ac_init) {
1229 for (id = id_min; id <= id_max; id++) {
1230 battery = &sbs->battery[id];
1231 if (battery->alive == 0) {
1235 old_remaining_capacity = battery->capacity_now;
1237 old_present = battery->present;
1239 result = acpi_battery_select(battery);
1241 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1242 "acpi_battery_select() failed"));
1245 result = acpi_battery_get_present(battery);
1247 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1248 "acpi_battery_get_present() failed"));
1251 new_present = battery->present;
1253 do_battery_init = ((old_present != new_present)
1257 if (do_ac_init || do_battery_init) {
1258 result = acpi_battery_init(battery);
1260 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1261 "acpi_battery_init() "
1265 if (sbs_zombie(sbs)) {
1269 if ((data_type == DATA_TYPE_COMMON
1270 || data_type == DATA_TYPE_INFO)
1272 result = acpi_battery_get_info(battery);
1274 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1275 "acpi_battery_get_info() failed"));
1278 if (data_type == DATA_TYPE_INFO) {
1281 if (sbs_zombie(sbs)) {
1285 if ((data_type == DATA_TYPE_COMMON
1286 || data_type == DATA_TYPE_STATE)
1288 result = acpi_battery_get_state(battery);
1290 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1291 "acpi_battery_get_state() failed"));
1294 if (data_type == DATA_TYPE_STATE) {
1297 if (sbs_zombie(sbs)) {
1301 if ((data_type == DATA_TYPE_COMMON
1302 || data_type == DATA_TYPE_ALARM)
1304 result = acpi_battery_get_alarm(battery);
1306 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1307 "acpi_battery_get_alarm() "
1311 if (data_type == DATA_TYPE_ALARM) {
1314 if (sbs_zombie(sbs)) {
1320 if (old_present != new_present || do_ac_init ||
1321 old_remaining_capacity !=
1322 battery->capacity_now) {
1323 sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id);
1324 result = acpi_bus_generate_proc_event4(ACPI_BATTERY_CLASS,
1326 ACPI_SBS_BATTERY_NOTIFY_STATUS,
1328 acpi_bus_generate_netlink_event(ACPI_BATTERY_CLASS, dir_name,
1329 ACPI_SBS_BATTERY_NOTIFY_STATUS,
1332 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1333 "acpi_bus_generate_proc_event4() "
1344 static void acpi_sbs_update_time(void *data)
1346 struct acpi_sbs *sbs = data;
1347 unsigned long delay = -1;
1349 unsigned int up_tm = update_time;
1351 if (sbs_mutex_lock(sbs))
1354 result = acpi_sbs_update_run(sbs, -1, DATA_TYPE_COMMON);
1356 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1357 "acpi_sbs_update_run() failed"));
1360 if (sbs_zombie(sbs)) {
1365 if (timer_pending(&sbs->update_timer))
1366 del_timer(&sbs->update_timer);
1368 delay = (up_tm > UPDATE_DELAY ? UPDATE_DELAY : up_tm);
1369 delay = jiffies + HZ * delay;
1370 if (timer_pending(&sbs->update_timer)) {
1371 mod_timer(&sbs->update_timer, delay);
1373 sbs->update_timer.data = (unsigned long)data;
1374 sbs->update_timer.function = acpi_sbs_update_time_run;
1375 sbs->update_timer.expires = delay;
1376 add_timer(&sbs->update_timer);
1382 sbs_mutex_unlock(sbs);
1385 static int acpi_sbs_add(struct acpi_device *device)
1387 struct acpi_sbs *sbs = NULL;
1388 int result = 0, remove_result = 0;
1391 sbs = kzalloc(sizeof(struct acpi_sbs), GFP_KERNEL);
1393 ACPI_EXCEPTION((AE_INFO, AE_ERROR, "kzalloc() failed"));
1398 mutex_init(&sbs->mutex);
1400 sbs_mutex_lock(sbs);
1402 sbs->device = device;
1403 sbs->hc = acpi_driver_data(device->parent);
1405 strcpy(acpi_device_name(device), ACPI_SBS_DEVICE_NAME);
1406 strcpy(acpi_device_class(device), ACPI_SBS_CLASS);
1407 acpi_driver_data(device) = sbs;
1409 result = acpi_ac_add(sbs);
1411 ACPI_EXCEPTION((AE_INFO, AE_ERROR, "acpi_ac_add() failed"));
1415 acpi_sbsm_get_info(sbs);
1417 if (!sbs->manager_present) {
1418 result = acpi_battery_add(sbs, 0);
1420 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1421 "acpi_battery_add() failed"));
1425 for (id = 0; id < MAX_SBS_BAT; id++) {
1426 if ((sbs->batteries_supported & (1 << id))) {
1427 result = acpi_battery_add(sbs, id);
1429 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1430 "acpi_battery_add() failed"));
1437 init_timer(&sbs->update_timer);
1438 result = acpi_check_update_proc(sbs);
1444 sbs_mutex_unlock(sbs);
1447 remove_result = acpi_sbs_remove(device, 0);
1448 if (remove_result) {
1449 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1450 "acpi_sbs_remove() failed"));
1457 static int acpi_sbs_remove(struct acpi_device *device, int type)
1459 struct acpi_sbs *sbs;
1466 sbs = acpi_driver_data(device);
1471 sbs_mutex_lock(sbs);
1474 del_timer_sync(&sbs->update_timer);
1475 acpi_os_wait_events_complete(NULL);
1476 del_timer_sync(&sbs->update_timer);
1478 for (id = 0; id < MAX_SBS_BAT; id++) {
1479 acpi_battery_remove(sbs, id);
1482 acpi_ac_remove(sbs);
1484 sbs_mutex_unlock(sbs);
1486 mutex_destroy(&sbs->mutex);
1493 static void acpi_sbs_rmdirs(void)
1496 acpi_unlock_ac_dir(acpi_ac_dir);
1499 if (acpi_battery_dir) {
1500 acpi_unlock_battery_dir(acpi_battery_dir);
1501 acpi_battery_dir = NULL;
1505 static int acpi_sbs_resume(struct acpi_device *device)
1507 struct acpi_sbs *sbs;
1512 sbs = device->driver_data;
1519 static int __init acpi_sbs_init(void)
1526 if (mode != DEF_CAPACITY_UNIT
1527 && mode != MAH_CAPACITY_UNIT
1528 && mode != MWH_CAPACITY_UNIT) {
1529 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1530 "invalid mode = %d", mode));
1534 acpi_ac_dir = acpi_lock_ac_dir();
1536 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1537 "acpi_lock_ac_dir() failed"));
1541 acpi_battery_dir = acpi_lock_battery_dir();
1542 if (!acpi_battery_dir) {
1543 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1544 "acpi_lock_battery_dir() failed"));
1549 result = acpi_bus_register_driver(&acpi_sbs_driver);
1551 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1552 "acpi_bus_register_driver() failed"));
1560 static void __exit acpi_sbs_exit(void)
1562 acpi_bus_unregister_driver(&acpi_sbs_driver);
1569 module_init(acpi_sbs_init);
1570 module_exit(acpi_sbs_exit);