ACPI: add support for Smart Battery
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / acpi / sbs.c
blob8bebcebff5f016e186ff7308be87ee3e2a7524f4
1 /*
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/i2c.h>
34 #include <linux/delay.h>
36 #include "i2c_ec.h"
38 #define DEF_CAPACITY_UNIT 3
39 #define MAH_CAPACITY_UNIT 1
40 #define MWH_CAPACITY_UNIT 2
41 #define CAPACITY_UNIT DEF_CAPACITY_UNIT
43 #define REQUEST_UPDATE_MODE 1
44 #define QUEUE_UPDATE_MODE 2
46 #define DATA_TYPE_COMMON 0
47 #define DATA_TYPE_INFO 1
48 #define DATA_TYPE_STATE 2
49 #define DATA_TYPE_ALARM 3
50 #define DATA_TYPE_AC_STATE 4
52 extern struct proc_dir_entry *acpi_lock_ac_dir(void);
53 extern struct proc_dir_entry *acpi_lock_battery_dir(void);
54 extern void acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir);
55 extern void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
57 #define ACPI_SBS_COMPONENT 0x00080000
58 #define ACPI_SBS_CLASS "sbs"
59 #define ACPI_AC_CLASS "ac_adapter"
60 #define ACPI_BATTERY_CLASS "battery"
61 #define ACPI_SBS_HID "ACPI0002"
62 #define ACPI_SBS_DRIVER_NAME "ACPI Smart Battery System Driver"
63 #define ACPI_SBS_DEVICE_NAME "Smart Battery System"
64 #define ACPI_SBS_FILE_INFO "info"
65 #define ACPI_SBS_FILE_STATE "state"
66 #define ACPI_SBS_FILE_ALARM "alarm"
67 #define ACPI_BATTERY_DIR_NAME "BAT%i"
68 #define ACPI_AC_DIR_NAME "AC0"
69 #define ACPI_SBC_SMBUS_ADDR 0x9
70 #define ACPI_SBSM_SMBUS_ADDR 0xa
71 #define ACPI_SB_SMBUS_ADDR 0xb
72 #define ACPI_SBS_AC_NOTIFY_STATUS 0x80
73 #define ACPI_SBS_BATTERY_NOTIFY_STATUS 0x80
74 #define ACPI_SBS_BATTERY_NOTIFY_INFO 0x81
76 #define _COMPONENT ACPI_SBS_COMPONENT
78 #define MAX_SBS_BAT 4
79 #define MAX_SMBUS_ERR 1
81 ACPI_MODULE_NAME("acpi_sbs");
83 MODULE_AUTHOR("Rich Townsend");
84 MODULE_DESCRIPTION("Smart Battery System ACPI interface driver");
85 MODULE_LICENSE("GPL");
87 static struct semaphore sbs_sem;
89 #define UPDATE_MODE QUEUE_UPDATE_MODE
90 /* REQUEST_UPDATE_MODE QUEUE_UPDATE_MODE */
91 #define UPDATE_INFO_MODE 0
92 #define UPDATE_TIME 60
93 #define UPDATE_TIME2 0
95 static int capacity_mode = CAPACITY_UNIT;
96 static int update_mode = UPDATE_MODE;
97 static int update_info_mode = UPDATE_INFO_MODE;
98 static int update_time = UPDATE_TIME;
99 static int update_time2 = UPDATE_TIME2;
101 module_param(capacity_mode, int, CAPACITY_UNIT);
102 module_param(update_mode, int, UPDATE_MODE);
103 module_param(update_info_mode, int, UPDATE_INFO_MODE);
104 module_param(update_time, int, UPDATE_TIME);
105 module_param(update_time2, int, UPDATE_TIME2);
107 static int acpi_sbs_add(struct acpi_device *device);
108 static int acpi_sbs_remove(struct acpi_device *device, int type);
109 static void acpi_battery_smbus_err_handler(struct acpi_ec_smbus *smbus);
110 static void acpi_sbs_update_queue(void *data);
112 static struct acpi_driver acpi_sbs_driver = {
113 .name = ACPI_SBS_DRIVER_NAME,
114 .class = ACPI_SBS_CLASS,
115 .ids = ACPI_SBS_HID,
116 .ops = {
117 .add = acpi_sbs_add,
118 .remove = acpi_sbs_remove,
122 struct acpi_battery_info {
123 int capacity_mode;
124 s16 full_charge_capacity;
125 s16 design_capacity;
126 s16 design_voltage;
127 int vscale;
128 int ipscale;
129 s16 serial_number;
130 char manufacturer_name[I2C_SMBUS_BLOCK_MAX + 3];
131 char device_name[I2C_SMBUS_BLOCK_MAX + 3];
132 char device_chemistry[I2C_SMBUS_BLOCK_MAX + 3];
135 struct acpi_battery_state {
136 s16 voltage;
137 s16 amperage;
138 s16 remaining_capacity;
139 s16 average_time_to_empty;
140 s16 average_time_to_full;
141 s16 battery_status;
144 struct acpi_battery_alarm {
145 s16 remaining_capacity;
148 struct acpi_battery {
149 int alive;
150 int battery_present;
151 int id;
152 int init_state;
153 struct acpi_sbs *sbs;
154 struct acpi_battery_info info;
155 struct acpi_battery_state state;
156 struct acpi_battery_alarm alarm;
157 struct proc_dir_entry *battery_entry;
160 struct acpi_sbs {
161 acpi_handle handle;
162 struct acpi_device *device;
163 struct acpi_ec_smbus *smbus;
164 int sbsm_present;
165 int sbsm_batteries_supported;
166 int ac_present;
167 struct proc_dir_entry *ac_entry;
168 struct acpi_battery battery[MAX_SBS_BAT];
169 int update_info_mode;
170 int zombie;
171 int update_time;
172 int update_time2;
173 struct timer_list update_timer;
176 static void acpi_update_delay(struct acpi_sbs *sbs);
177 static int acpi_sbs_update_run(struct acpi_sbs *sbs, int data_type);
179 /* --------------------------------------------------------------------------
180 SMBus Communication
181 -------------------------------------------------------------------------- */
183 static void acpi_battery_smbus_err_handler(struct acpi_ec_smbus *smbus)
185 union i2c_smbus_data data;
186 int result = 0;
187 char *err_str;
188 int err_number;
190 ACPI_FUNCTION_TRACE("acpi_battery_smbus_err_handler");
192 data.word = 0;
194 result = smbus->adapter.algo->
195 smbus_xfer(&smbus->adapter,
196 ACPI_SB_SMBUS_ADDR,
197 0, I2C_SMBUS_READ, 0x16, I2C_SMBUS_BLOCK_DATA, &data);
199 err_number = (data.word & 0x000f);
201 switch (data.word & 0x000f) {
202 case 0x0000:
203 err_str = "unexpected bus error";
204 break;
205 case 0x0001:
206 err_str = "busy";
207 break;
208 case 0x0002:
209 err_str = "reserved command";
210 break;
211 case 0x0003:
212 err_str = "unsupported command";
213 break;
214 case 0x0004:
215 err_str = "access denied";
216 break;
217 case 0x0005:
218 err_str = "overflow/underflow";
219 break;
220 case 0x0006:
221 err_str = "bad size";
222 break;
223 case 0x0007:
224 err_str = "unknown error";
225 break;
226 default:
227 err_str = "unrecognized error";
229 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
230 "%s: ret %i, err %i\n", err_str, result, err_number));
233 static int
234 acpi_sbs_smbus_read_word(struct acpi_ec_smbus *smbus, int addr, int func,
235 u16 * word,
236 void (*err_handler) (struct acpi_ec_smbus * smbus))
238 union i2c_smbus_data data;
239 int result = 0;
240 int i;
242 ACPI_FUNCTION_TRACE("acpi_sbs_smbus_read_word");
244 if (err_handler == NULL) {
245 err_handler = acpi_battery_smbus_err_handler;
248 for (i = 0; i < MAX_SMBUS_ERR; i++) {
249 result =
250 smbus->adapter.algo->smbus_xfer(&smbus->adapter, addr, 0,
251 I2C_SMBUS_READ, func,
252 I2C_SMBUS_WORD_DATA, &data);
253 if (result) {
254 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
255 "try %i: smbus->adapter.algo->smbus_xfer() failed\n",
256 i));
257 if (err_handler) {
258 err_handler(smbus);
260 } else {
261 *word = data.word;
262 break;
266 return_VALUE(result);
269 static int
270 acpi_sbs_smbus_read_str(struct acpi_ec_smbus *smbus, int addr, int func,
271 char *str,
272 void (*err_handler) (struct acpi_ec_smbus * smbus))
274 union i2c_smbus_data data;
275 int result = 0;
276 int i;
278 ACPI_FUNCTION_TRACE("acpi_sbs_smbus_read_str");
280 if (err_handler == NULL) {
281 err_handler = acpi_battery_smbus_err_handler;
284 for (i = 0; i < MAX_SMBUS_ERR; i++) {
285 result =
286 smbus->adapter.algo->smbus_xfer(&smbus->adapter, addr, 0,
287 I2C_SMBUS_READ, func,
288 I2C_SMBUS_BLOCK_DATA,
289 &data);
290 if (result) {
291 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
292 "try %i: smbus->adapter.algo->smbus_xfer() failed\n",
293 i));
294 if (err_handler) {
295 err_handler(smbus);
297 } else {
298 strncpy(str, (const char *)data.block + 1,
299 data.block[0]);
300 str[data.block[0]] = 0;
301 break;
305 return_VALUE(result);
308 static int
309 acpi_sbs_smbus_write_word(struct acpi_ec_smbus *smbus, int addr, int func,
310 int word,
311 void (*err_handler) (struct acpi_ec_smbus * smbus))
313 union i2c_smbus_data data;
314 int result = 0;
315 int i;
317 ACPI_FUNCTION_TRACE("acpi_sbs_smbus_write_word");
319 if (err_handler == NULL) {
320 err_handler = acpi_battery_smbus_err_handler;
323 data.word = word;
325 for (i = 0; i < MAX_SMBUS_ERR; i++) {
326 result =
327 smbus->adapter.algo->smbus_xfer(&smbus->adapter, addr, 0,
328 I2C_SMBUS_WRITE, func,
329 I2C_SMBUS_WORD_DATA, &data);
330 if (result) {
331 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
332 "try %i: smbus->adapter.algo"
333 "->smbus_xfer() failed\n", i));
334 if (err_handler) {
335 err_handler(smbus);
337 } else {
338 break;
342 return_VALUE(result);
345 /* --------------------------------------------------------------------------
346 Smart Battery System Management
347 -------------------------------------------------------------------------- */
349 /* Smart Battery */
351 static int acpi_sbs_generate_event(struct acpi_device *device,
352 int event, int state, char *bid, char *class)
354 char bid_saved[5];
355 char class_saved[20];
356 int result = 0;
358 ACPI_FUNCTION_TRACE("acpi_sbs_generate_event");
360 strcpy(bid_saved, acpi_device_bid(device));
361 strcpy(class_saved, acpi_device_class(device));
363 strcpy(acpi_device_bid(device), bid);
364 strcpy(acpi_device_class(device), class);
366 result = acpi_bus_generate_event(device, event, state);
368 strcpy(acpi_device_bid(device), bid_saved);
369 strcpy(acpi_device_class(device), class_saved);
371 return_VALUE(result);
374 static int acpi_battery_get_present(struct acpi_battery *battery)
376 s16 state;
377 int result = 0;
378 int is_present = 0;
380 ACPI_FUNCTION_TRACE("acpi_battery_get_present");
382 result = acpi_sbs_smbus_read_word(battery->sbs->smbus,
383 ACPI_SBSM_SMBUS_ADDR, 0x01,
384 &state, NULL);
385 if (result) {
386 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
387 "acpi_sbs_smbus_read_word() failed"));
389 if (!result) {
390 is_present = (state & 0x000f) & (1 << battery->id);
392 battery->battery_present = is_present;
394 return_VALUE(result);
397 static int acpi_battery_is_present(struct acpi_battery *battery)
399 return (battery->battery_present);
402 static int acpi_ac_is_present(struct acpi_sbs *sbs)
404 return (sbs->ac_present);
407 static int acpi_battery_select(struct acpi_battery *battery)
409 struct acpi_ec_smbus *smbus = battery->sbs->smbus;
410 int result = 0;
411 s16 state;
412 int foo;
414 ACPI_FUNCTION_TRACE("acpi_battery_select");
416 if (battery->sbs->sbsm_present) {
418 /* Take special care not to knobble other nibbles of
419 * state (aka selector_state), since
420 * it causes charging to halt on SBSELs */
422 result =
423 acpi_sbs_smbus_read_word(smbus, ACPI_SBSM_SMBUS_ADDR, 0x01,
424 &state, NULL);
425 if (result) {
426 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
427 "acpi_sbs_smbus_read_word() failed\n"));
428 goto end;
431 foo = (state & 0x0fff) | (1 << (battery->id + 12));
432 result =
433 acpi_sbs_smbus_write_word(smbus, ACPI_SBSM_SMBUS_ADDR, 0x01,
434 foo, NULL);
435 if (result) {
436 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
437 "acpi_sbs_smbus_write_word() failed\n"));
438 goto end;
442 end:
443 return_VALUE(result);
446 static int acpi_sbsm_get_info(struct acpi_sbs *sbs)
448 struct acpi_ec_smbus *smbus = sbs->smbus;
449 int result = 0;
450 s16 battery_system_info;
452 ACPI_FUNCTION_TRACE("acpi_sbsm_get_info");
454 result = acpi_sbs_smbus_read_word(smbus, ACPI_SBSM_SMBUS_ADDR, 0x04,
455 &battery_system_info, NULL);
456 if (result) {
457 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
458 "acpi_sbs_smbus_read_word() failed\n"));
459 goto end;
462 sbs->sbsm_batteries_supported = battery_system_info & 0x000f;
464 end:
466 return_VALUE(result);
469 static int acpi_battery_get_info(struct acpi_battery *battery)
471 struct acpi_ec_smbus *smbus = battery->sbs->smbus;
472 int result = 0;
473 s16 battery_mode;
474 s16 specification_info;
476 ACPI_FUNCTION_TRACE("acpi_battery_get_info");
478 result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x03,
479 &battery_mode,
480 &acpi_battery_smbus_err_handler);
481 if (result) {
482 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
483 "acpi_sbs_smbus_read_word() failed\n"));
484 goto end;
486 battery->info.capacity_mode = (battery_mode & 0x8000) >> 15;
488 result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x10,
489 &battery->info.full_charge_capacity,
490 &acpi_battery_smbus_err_handler);
491 if (result) {
492 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
493 "acpi_sbs_smbus_read_word() failed\n"));
494 goto end;
497 result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x18,
498 &battery->info.design_capacity,
499 &acpi_battery_smbus_err_handler);
501 if (result) {
502 goto end;
505 result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x19,
506 &battery->info.design_voltage,
507 &acpi_battery_smbus_err_handler);
508 if (result) {
509 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
510 "acpi_sbs_smbus_read_word() failed\n"));
511 goto end;
514 result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x1a,
515 &specification_info,
516 &acpi_battery_smbus_err_handler);
517 if (result) {
518 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
519 "acpi_sbs_smbus_read_word() failed\n"));
520 goto end;
523 switch ((specification_info & 0x0f00) >> 8) {
524 case 1:
525 battery->info.vscale = 10;
526 break;
527 case 2:
528 battery->info.vscale = 100;
529 break;
530 case 3:
531 battery->info.vscale = 1000;
532 break;
533 default:
534 battery->info.vscale = 1;
537 switch ((specification_info & 0xf000) >> 12) {
538 case 1:
539 battery->info.ipscale = 10;
540 break;
541 case 2:
542 battery->info.ipscale = 100;
543 break;
544 case 3:
545 battery->info.ipscale = 1000;
546 break;
547 default:
548 battery->info.ipscale = 1;
551 result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x1c,
552 &battery->info.serial_number,
553 &acpi_battery_smbus_err_handler);
554 if (result) {
555 goto end;
558 result = acpi_sbs_smbus_read_str(smbus, ACPI_SB_SMBUS_ADDR, 0x20,
559 battery->info.manufacturer_name,
560 &acpi_battery_smbus_err_handler);
561 if (result) {
562 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
563 "acpi_sbs_smbus_read_str() failed\n"));
564 goto end;
567 result = acpi_sbs_smbus_read_str(smbus, ACPI_SB_SMBUS_ADDR, 0x21,
568 battery->info.device_name,
569 &acpi_battery_smbus_err_handler);
570 if (result) {
571 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
572 "acpi_sbs_smbus_read_str() failed\n"));
573 goto end;
576 result = acpi_sbs_smbus_read_str(smbus, ACPI_SB_SMBUS_ADDR, 0x22,
577 battery->info.device_chemistry,
578 &acpi_battery_smbus_err_handler);
579 if (result) {
580 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
581 "acpi_sbs_smbus_read_str() failed\n"));
582 goto end;
585 end:
586 return_VALUE(result);
589 static void acpi_update_delay(struct acpi_sbs *sbs)
591 ACPI_FUNCTION_TRACE("acpi_update_delay");
592 if (sbs->zombie) {
593 return;
595 if (sbs->update_time2 > 0) {
596 msleep(sbs->update_time2 * 1000);
600 static int acpi_battery_get_state(struct acpi_battery *battery)
602 struct acpi_ec_smbus *smbus = battery->sbs->smbus;
603 int result = 0;
605 ACPI_FUNCTION_TRACE("acpi_battery_get_state");
607 acpi_update_delay(battery->sbs);
608 result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x09,
609 &battery->state.voltage,
610 &acpi_battery_smbus_err_handler);
611 if (result) {
612 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
613 "acpi_sbs_smbus_read_word() failed\n"));
614 goto end;
617 acpi_update_delay(battery->sbs);
618 result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x0a,
619 &battery->state.amperage,
620 &acpi_battery_smbus_err_handler);
621 if (result) {
622 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
623 "acpi_sbs_smbus_read_word() failed\n"));
624 goto end;
627 acpi_update_delay(battery->sbs);
628 result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x0f,
629 &battery->state.remaining_capacity,
630 &acpi_battery_smbus_err_handler);
631 if (result) {
632 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
633 "acpi_sbs_smbus_read_word() failed\n"));
634 goto end;
637 acpi_update_delay(battery->sbs);
638 result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x12,
639 &battery->state.average_time_to_empty,
640 &acpi_battery_smbus_err_handler);
641 if (result) {
642 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
643 "acpi_sbs_smbus_read_word() failed\n"));
644 goto end;
647 acpi_update_delay(battery->sbs);
648 result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x13,
649 &battery->state.average_time_to_full,
650 &acpi_battery_smbus_err_handler);
651 if (result) {
652 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
653 "acpi_sbs_smbus_read_word() failed\n"));
654 goto end;
657 acpi_update_delay(battery->sbs);
658 result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x16,
659 &battery->state.battery_status,
660 &acpi_battery_smbus_err_handler);
661 if (result) {
662 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
663 "acpi_sbs_smbus_read_word() failed\n"));
664 goto end;
667 acpi_update_delay(battery->sbs);
669 end:
670 return_VALUE(result);
673 static int acpi_battery_get_alarm(struct acpi_battery *battery)
675 struct acpi_ec_smbus *smbus = battery->sbs->smbus;
676 int result = 0;
678 ACPI_FUNCTION_TRACE("acpi_battery_get_alarm");
680 result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x01,
681 &battery->alarm.remaining_capacity,
682 &acpi_battery_smbus_err_handler);
683 if (result) {
684 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
685 "acpi_sbs_smbus_read_word() failed\n"));
686 goto end;
689 acpi_update_delay(battery->sbs);
691 end:
693 return_VALUE(result);
696 static int acpi_battery_set_alarm(struct acpi_battery *battery,
697 unsigned long alarm)
699 struct acpi_ec_smbus *smbus = battery->sbs->smbus;
700 int result = 0;
701 s16 battery_mode;
702 int foo;
704 ACPI_FUNCTION_TRACE("acpi_battery_set_alarm");
706 result = acpi_battery_select(battery);
707 if (result) {
708 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
709 "acpi_battery_select() failed\n"));
710 goto end;
713 /* If necessary, enable the alarm */
715 if (alarm > 0) {
716 result =
717 acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x03,
718 &battery_mode,
719 &acpi_battery_smbus_err_handler);
720 if (result) {
721 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
722 "acpi_sbs_smbus_read_word() failed\n"));
723 goto end;
726 result =
727 acpi_sbs_smbus_write_word(smbus, ACPI_SB_SMBUS_ADDR, 0x01,
728 battery_mode & 0xbfff,
729 &acpi_battery_smbus_err_handler);
730 if (result) {
731 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
732 "acpi_sbs_smbus_write_word() failed\n"));
733 goto end;
737 foo = alarm / (battery->info.capacity_mode ? 10 : 1);
738 result = acpi_sbs_smbus_write_word(smbus, ACPI_SB_SMBUS_ADDR, 0x01,
739 foo,
740 &acpi_battery_smbus_err_handler);
741 if (result) {
742 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
743 "acpi_sbs_smbus_write_word() failed\n"));
744 goto end;
747 end:
749 return_VALUE(result);
752 static int acpi_battery_set_mode(struct acpi_battery *battery)
754 int result = 0;
755 s16 battery_mode;
757 ACPI_FUNCTION_TRACE("acpi_battery_set_mode");
759 if (capacity_mode == DEF_CAPACITY_UNIT) {
760 goto end;
763 result = acpi_sbs_smbus_read_word(battery->sbs->smbus,
764 ACPI_SB_SMBUS_ADDR, 0x03,
765 &battery_mode, NULL);
766 if (result) {
767 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
768 "acpi_sbs_smbus_read_word() failed\n"));
769 goto end;
772 if (capacity_mode == MAH_CAPACITY_UNIT) {
773 battery_mode &= 0x7fff;
774 } else {
775 battery_mode |= 0x8000;
777 result = acpi_sbs_smbus_write_word(battery->sbs->smbus,
778 ACPI_SB_SMBUS_ADDR, 0x03,
779 battery_mode, NULL);
780 if (result) {
781 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
782 "acpi_sbs_smbus_write_word() failed\n"));
783 goto end;
786 result = acpi_sbs_smbus_read_word(battery->sbs->smbus,
787 ACPI_SB_SMBUS_ADDR, 0x03,
788 &battery_mode, NULL);
789 if (result) {
790 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
791 "acpi_sbs_smbus_read_word() failed\n"));
792 goto end;
795 end:
796 return_VALUE(result);
799 static int acpi_battery_init(struct acpi_battery *battery)
801 int result = 0;
803 ACPI_FUNCTION_TRACE("acpi_battery_init");
805 result = acpi_battery_select(battery);
806 if (result) {
807 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
808 "acpi_battery_init() failed\n"));
809 goto end;
812 result = acpi_battery_set_mode(battery);
813 if (result) {
814 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
815 "acpi_battery_set_mode() failed\n"));
816 goto end;
819 result = acpi_battery_get_info(battery);
820 if (result) {
821 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
822 "acpi_battery_get_info() failed\n"));
823 goto end;
826 result = acpi_battery_get_state(battery);
827 if (result) {
828 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
829 "acpi_battery_get_state() failed\n"));
830 goto end;
833 result = acpi_battery_get_alarm(battery);
834 if (result) {
835 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
836 "acpi_battery_get_alarm() failed\n"));
837 goto end;
840 end:
841 return_VALUE(result);
844 static int acpi_ac_get_present(struct acpi_sbs *sbs)
846 struct acpi_ec_smbus *smbus = sbs->smbus;
847 int result = 0;
848 s16 charger_status;
850 ACPI_FUNCTION_TRACE("acpi_ac_get_present");
852 result = acpi_sbs_smbus_read_word(smbus, ACPI_SBC_SMBUS_ADDR, 0x13,
853 &charger_status, NULL);
855 if (result) {
856 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
857 "acpi_sbs_smbus_read_word() failed\n"));
858 goto end;
861 sbs->ac_present = (charger_status & 0x8000) >> 15;
863 end:
865 return_VALUE(result);
868 /* --------------------------------------------------------------------------
869 FS Interface (/proc/acpi)
870 -------------------------------------------------------------------------- */
872 /* Generic Routines */
874 static int
875 acpi_sbs_generic_add_fs(struct proc_dir_entry **dir,
876 struct proc_dir_entry *parent_dir,
877 char *dir_name,
878 struct file_operations *info_fops,
879 struct file_operations *state_fops,
880 struct file_operations *alarm_fops, void *data)
882 struct proc_dir_entry *entry = NULL;
884 ACPI_FUNCTION_TRACE("acpi_sbs_generic_add_fs");
886 if (!*dir) {
887 *dir = proc_mkdir(dir_name, parent_dir);
888 if (!*dir) {
889 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
890 "proc_mkdir() failed\n"));
891 return_VALUE(-ENODEV);
893 (*dir)->owner = THIS_MODULE;
896 /* 'info' [R] */
897 if (info_fops) {
898 entry = create_proc_entry(ACPI_SBS_FILE_INFO, S_IRUGO, *dir);
899 if (!entry) {
900 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
901 "create_proc_entry() failed\n"));
902 } else {
903 entry->proc_fops = info_fops;
904 entry->data = data;
905 entry->owner = THIS_MODULE;
909 /* 'state' [R] */
910 if (state_fops) {
911 entry = create_proc_entry(ACPI_SBS_FILE_STATE, S_IRUGO, *dir);
912 if (!entry) {
913 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
914 "create_proc_entry() failed\n"));
915 } else {
916 entry->proc_fops = state_fops;
917 entry->data = data;
918 entry->owner = THIS_MODULE;
922 /* 'alarm' [R/W] */
923 if (alarm_fops) {
924 entry = create_proc_entry(ACPI_SBS_FILE_ALARM, S_IRUGO, *dir);
925 if (!entry) {
926 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
927 "create_proc_entry() failed\n"));
928 } else {
929 entry->proc_fops = alarm_fops;
930 entry->data = data;
931 entry->owner = THIS_MODULE;
935 return_VALUE(0);
938 static void
939 acpi_sbs_generic_remove_fs(struct proc_dir_entry **dir,
940 struct proc_dir_entry *parent_dir)
942 ACPI_FUNCTION_TRACE("acpi_sbs_generic_remove_fs");
944 if (*dir) {
945 remove_proc_entry(ACPI_SBS_FILE_INFO, *dir);
946 remove_proc_entry(ACPI_SBS_FILE_STATE, *dir);
947 remove_proc_entry(ACPI_SBS_FILE_ALARM, *dir);
948 remove_proc_entry((*dir)->name, parent_dir);
949 *dir = NULL;
954 /* Smart Battery Interface */
956 static struct proc_dir_entry *acpi_battery_dir = NULL;
958 static int acpi_battery_read_info(struct seq_file *seq, void *offset)
960 struct acpi_battery *battery = (struct acpi_battery *)seq->private;
961 int cscale;
962 int result = 0;
964 ACPI_FUNCTION_TRACE("acpi_battery_read_info");
966 if (battery->sbs->zombie) {
967 return_VALUE(-ENODEV);
970 down(&sbs_sem);
972 if (update_mode == REQUEST_UPDATE_MODE) {
973 result = acpi_sbs_update_run(battery->sbs, DATA_TYPE_INFO);
974 if (result) {
975 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
976 "acpi_sbs_update_run() failed\n"));
980 if (acpi_battery_is_present(battery)) {
981 seq_printf(seq, "present: yes\n");
982 } else {
983 seq_printf(seq, "present: no\n");
984 goto end;
987 if (battery->info.capacity_mode) {
988 cscale = battery->info.vscale * battery->info.ipscale;
989 } else {
990 cscale = battery->info.ipscale;
992 seq_printf(seq, "design capacity: %i%s",
993 battery->info.design_capacity * cscale,
994 battery->info.capacity_mode ? "0 mWh\n" : " mAh\n");
996 seq_printf(seq, "last full capacity: %i%s",
997 battery->info.full_charge_capacity * cscale,
998 battery->info.capacity_mode ? "0 mWh\n" : " mAh\n");
1000 seq_printf(seq, "battery technology: rechargeable\n");
1002 seq_printf(seq, "design voltage: %i mV\n",
1003 battery->info.design_voltage * battery->info.vscale);
1005 seq_printf(seq, "design capacity warning: unknown\n");
1006 seq_printf(seq, "design capacity low: unknown\n");
1007 seq_printf(seq, "capacity granularity 1: unknown\n");
1008 seq_printf(seq, "capacity granularity 2: unknown\n");
1010 seq_printf(seq, "model number: %s\n",
1011 battery->info.device_name);
1013 seq_printf(seq, "serial number: %i\n",
1014 battery->info.serial_number);
1016 seq_printf(seq, "battery type: %s\n",
1017 battery->info.device_chemistry);
1019 seq_printf(seq, "OEM info: %s\n",
1020 battery->info.manufacturer_name);
1022 end:
1024 up(&sbs_sem);
1026 return_VALUE(result);
1029 static int acpi_battery_info_open_fs(struct inode *inode, struct file *file)
1031 return single_open(file, acpi_battery_read_info, PDE(inode)->data);
1034 static int acpi_battery_read_state(struct seq_file *seq, void *offset)
1036 struct acpi_battery *battery = (struct acpi_battery *)seq->private;
1037 int result = 0;
1038 int cscale;
1039 int foo;
1041 ACPI_FUNCTION_TRACE("acpi_battery_read_state");
1043 if (battery->sbs->zombie) {
1044 return_VALUE(-ENODEV);
1047 down(&sbs_sem);
1049 if (update_mode == REQUEST_UPDATE_MODE) {
1050 result = acpi_sbs_update_run(battery->sbs, DATA_TYPE_STATE);
1051 if (result) {
1052 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1053 "acpi_sbs_update_run() failed\n"));
1057 if (acpi_battery_is_present(battery)) {
1058 seq_printf(seq, "present: yes\n");
1059 } else {
1060 seq_printf(seq, "present: no\n");
1061 goto end;
1064 if (battery->info.capacity_mode) {
1065 cscale = battery->info.vscale * battery->info.ipscale;
1066 } else {
1067 cscale = battery->info.ipscale;
1070 if (battery->state.battery_status & 0x0010) {
1071 seq_printf(seq, "capacity state: critical\n");
1072 } else {
1073 seq_printf(seq, "capacity state: ok\n");
1075 if (battery->state.amperage < 0) {
1076 seq_printf(seq, "charging state: discharging\n");
1077 foo = battery->state.remaining_capacity * cscale * 60 /
1078 (battery->state.average_time_to_empty == 0 ? 1 :
1079 battery->state.average_time_to_empty);
1080 seq_printf(seq, "present rate: %i%s\n",
1081 foo, battery->info.capacity_mode ? "0 mW" : " mA");
1082 } else if (battery->state.amperage > 0) {
1083 seq_printf(seq, "charging state: charging\n");
1084 foo = (battery->info.full_charge_capacity -
1085 battery->state.remaining_capacity) * cscale * 60 /
1086 (battery->state.average_time_to_full == 0 ? 1 :
1087 battery->state.average_time_to_full);
1088 seq_printf(seq, "present rate: %i%s\n",
1089 foo, battery->info.capacity_mode ? "0 mW" : " mA");
1090 } else {
1091 seq_printf(seq, "charging state: charged\n");
1092 seq_printf(seq, "present rate: 0 %s\n",
1093 battery->info.capacity_mode ? "mW" : "mA");
1096 seq_printf(seq, "remaining capacity: %i%s",
1097 battery->state.remaining_capacity * cscale,
1098 battery->info.capacity_mode ? "0 mWh\n" : " mAh\n");
1100 seq_printf(seq, "present voltage: %i mV\n",
1101 battery->state.voltage * battery->info.vscale);
1103 end:
1105 up(&sbs_sem);
1107 return_VALUE(result);
1110 static int acpi_battery_state_open_fs(struct inode *inode, struct file *file)
1112 return single_open(file, acpi_battery_read_state, PDE(inode)->data);
1115 static int acpi_battery_read_alarm(struct seq_file *seq, void *offset)
1117 struct acpi_battery *battery = (struct acpi_battery *)seq->private;
1118 int result = 0;
1119 int cscale;
1121 ACPI_FUNCTION_TRACE("acpi_battery_read_alarm");
1123 if (battery->sbs->zombie) {
1124 return_VALUE(-ENODEV);
1127 down(&sbs_sem);
1129 if (update_mode == REQUEST_UPDATE_MODE) {
1130 result = acpi_sbs_update_run(battery->sbs, DATA_TYPE_ALARM);
1131 if (result) {
1132 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1133 "acpi_sbs_update_run() failed\n"));
1137 if (!acpi_battery_is_present(battery)) {
1138 seq_printf(seq, "present: no\n");
1139 goto end;
1142 if (battery->info.capacity_mode) {
1143 cscale = battery->info.vscale * battery->info.ipscale;
1144 } else {
1145 cscale = battery->info.ipscale;
1148 seq_printf(seq, "alarm: ");
1149 if (battery->alarm.remaining_capacity) {
1150 seq_printf(seq, "%i%s",
1151 battery->alarm.remaining_capacity * cscale,
1152 battery->info.capacity_mode ? "0 mWh\n" : " mAh\n");
1153 } else {
1154 seq_printf(seq, "disabled\n");
1157 end:
1159 up(&sbs_sem);
1161 return_VALUE(result);
1164 static ssize_t
1165 acpi_battery_write_alarm(struct file *file, const char __user * buffer,
1166 size_t count, loff_t * ppos)
1168 struct seq_file *seq = (struct seq_file *)file->private_data;
1169 struct acpi_battery *battery = (struct acpi_battery *)seq->private;
1170 char alarm_string[12] = { '\0' };
1171 int result, old_alarm, new_alarm;
1173 ACPI_FUNCTION_TRACE("acpi_battery_write_alarm");
1175 if (battery->sbs->zombie) {
1176 return_VALUE(-ENODEV);
1179 down(&sbs_sem);
1181 if (!acpi_battery_is_present(battery)) {
1182 result = -ENODEV;
1183 goto end;
1186 if (count > sizeof(alarm_string) - 1) {
1187 result = -EINVAL;
1188 goto end;
1191 if (copy_from_user(alarm_string, buffer, count)) {
1192 result = -EFAULT;
1193 goto end;
1196 alarm_string[count] = 0;
1198 old_alarm = battery->alarm.remaining_capacity;
1199 new_alarm = simple_strtoul(alarm_string, NULL, 0);
1201 result = acpi_battery_set_alarm(battery, new_alarm);
1202 if (result) {
1203 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1204 "acpi_battery_set_alarm() failed\n"));
1205 (void)acpi_battery_set_alarm(battery, old_alarm);
1206 goto end;
1208 result = acpi_battery_get_alarm(battery);
1209 if (result) {
1210 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1211 "acpi_battery_get_alarm() failed\n"));
1212 (void)acpi_battery_set_alarm(battery, old_alarm);
1213 goto end;
1216 end:
1217 up(&sbs_sem);
1219 if (result) {
1220 return_VALUE(result);
1221 } else {
1222 return_VALUE(count);
1226 static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file)
1228 return single_open(file, acpi_battery_read_alarm, PDE(inode)->data);
1231 static struct file_operations acpi_battery_info_fops = {
1232 .open = acpi_battery_info_open_fs,
1233 .read = seq_read,
1234 .llseek = seq_lseek,
1235 .release = single_release,
1236 .owner = THIS_MODULE,
1239 static struct file_operations acpi_battery_state_fops = {
1240 .open = acpi_battery_state_open_fs,
1241 .read = seq_read,
1242 .llseek = seq_lseek,
1243 .release = single_release,
1244 .owner = THIS_MODULE,
1247 static struct file_operations acpi_battery_alarm_fops = {
1248 .open = acpi_battery_alarm_open_fs,
1249 .read = seq_read,
1250 .write = acpi_battery_write_alarm,
1251 .llseek = seq_lseek,
1252 .release = single_release,
1253 .owner = THIS_MODULE,
1256 /* Legacy AC Adapter Interface */
1258 static struct proc_dir_entry *acpi_ac_dir = NULL;
1260 static int acpi_ac_read_state(struct seq_file *seq, void *offset)
1262 struct acpi_sbs *sbs = (struct acpi_sbs *)seq->private;
1263 int result;
1265 ACPI_FUNCTION_TRACE("acpi_ac_read_state");
1267 if (sbs->zombie) {
1268 return_VALUE(-ENODEV);
1271 down(&sbs_sem);
1273 if (update_mode == REQUEST_UPDATE_MODE) {
1274 result = acpi_sbs_update_run(sbs, DATA_TYPE_AC_STATE);
1275 if (result) {
1276 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1277 "acpi_sbs_update_run() failed\n"));
1281 seq_printf(seq, "state: %s\n",
1282 sbs->ac_present ? "on-line" : "off-line");
1284 up(&sbs_sem);
1286 return_VALUE(0);
1289 static int acpi_ac_state_open_fs(struct inode *inode, struct file *file)
1291 return single_open(file, acpi_ac_read_state, PDE(inode)->data);
1294 static struct file_operations acpi_ac_state_fops = {
1295 .open = acpi_ac_state_open_fs,
1296 .read = seq_read,
1297 .llseek = seq_lseek,
1298 .release = single_release,
1299 .owner = THIS_MODULE,
1302 /* --------------------------------------------------------------------------
1303 Driver Interface
1304 -------------------------------------------------------------------------- */
1306 /* Smart Battery */
1308 static int acpi_battery_add(struct acpi_sbs *sbs, int id)
1310 int is_present;
1311 int result;
1312 char dir_name[32];
1313 struct acpi_battery *battery;
1315 ACPI_FUNCTION_TRACE("acpi_battery_add");
1317 battery = &sbs->battery[id];
1319 battery->alive = 0;
1321 battery->init_state = 0;
1322 battery->id = id;
1323 battery->sbs = sbs;
1325 result = acpi_battery_select(battery);
1326 if (result) {
1327 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1328 "acpi_battery_select() failed\n"));
1329 goto end;
1332 result = acpi_battery_get_present(battery);
1333 if (result) {
1334 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1335 "acpi_battery_get_present() failed\n"));
1336 goto end;
1339 is_present = acpi_battery_is_present(battery);
1341 if (is_present) {
1342 result = acpi_battery_init(battery);
1343 if (result) {
1344 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1345 "acpi_battery_init() failed\n"));
1346 goto end;
1348 battery->init_state = 1;
1351 (void)sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id);
1353 result = acpi_sbs_generic_add_fs(&battery->battery_entry,
1354 acpi_battery_dir,
1355 dir_name,
1356 &acpi_battery_info_fops,
1357 &acpi_battery_state_fops,
1358 &acpi_battery_alarm_fops, battery);
1359 if (result) {
1360 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1361 "acpi_sbs_generic_add_fs() failed\n"));
1362 goto end;
1364 battery->alive = 1;
1366 end:
1367 return_VALUE(result);
1370 static void acpi_battery_remove(struct acpi_sbs *sbs, int id)
1372 ACPI_FUNCTION_TRACE("acpi_battery_remove");
1374 if (sbs->battery[id].battery_entry) {
1375 acpi_sbs_generic_remove_fs(&(sbs->battery[id].battery_entry),
1376 acpi_battery_dir);
1380 static int acpi_ac_add(struct acpi_sbs *sbs)
1382 int result;
1384 ACPI_FUNCTION_TRACE("acpi_ac_add");
1386 result = acpi_ac_get_present(sbs);
1387 if (result) {
1388 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1389 "acpi_ac_get_present() failed\n"));
1390 goto end;
1393 result = acpi_sbs_generic_add_fs(&sbs->ac_entry,
1394 acpi_ac_dir,
1395 ACPI_AC_DIR_NAME,
1396 NULL, &acpi_ac_state_fops, NULL, sbs);
1397 if (result) {
1398 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1399 "acpi_sbs_generic_add_fs() failed\n"));
1400 goto end;
1403 end:
1405 return_VALUE(result);
1408 static void acpi_ac_remove(struct acpi_sbs *sbs)
1410 ACPI_FUNCTION_TRACE("acpi_ac_remove");
1412 if (sbs->ac_entry) {
1413 acpi_sbs_generic_remove_fs(&sbs->ac_entry, acpi_ac_dir);
1417 static void acpi_sbs_update_queue_run(unsigned long data)
1419 ACPI_FUNCTION_TRACE("acpi_sbs_update_queue_run");
1420 acpi_os_execute(OSL_GPE_HANDLER, acpi_sbs_update_queue, (void *)data);
1423 static int acpi_sbs_update_run(struct acpi_sbs *sbs, int data_type)
1425 struct acpi_battery *battery;
1426 int result = 0;
1427 int old_ac_present;
1428 int old_battery_present;
1429 int new_ac_present;
1430 int new_battery_present;
1431 int id;
1432 char dir_name[32];
1433 int do_battery_init, do_ac_init;
1434 s16 old_remaining_capacity;
1436 ACPI_FUNCTION_TRACE("acpi_sbs_update_run");
1438 if (sbs->zombie) {
1439 goto end;
1442 old_ac_present = acpi_ac_is_present(sbs);
1444 result = acpi_ac_get_present(sbs);
1445 if (result) {
1446 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1447 "acpi_ac_get_present() failed\n"));
1450 new_ac_present = acpi_ac_is_present(sbs);
1452 do_ac_init = (old_ac_present != new_ac_present);
1454 if (data_type == DATA_TYPE_AC_STATE) {
1455 goto end;
1458 for (id = 0; id < MAX_SBS_BAT; id++) {
1459 battery = &sbs->battery[id];
1460 if (battery->alive == 0) {
1461 continue;
1464 old_remaining_capacity = battery->state.remaining_capacity;
1466 old_battery_present = acpi_battery_is_present(battery);
1468 result = acpi_battery_select(battery);
1469 if (result) {
1470 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1471 "acpi_battery_select() failed\n"));
1473 if (sbs->zombie) {
1474 goto end;
1477 result = acpi_battery_get_present(battery);
1478 if (result) {
1479 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1480 "acpi_battery_get_present() failed\n"));
1482 if (sbs->zombie) {
1483 goto end;
1486 new_battery_present = acpi_battery_is_present(battery);
1488 do_battery_init = ((old_battery_present != new_battery_present)
1489 && new_battery_present);
1491 if (sbs->zombie) {
1492 goto end;
1494 if (do_ac_init || do_battery_init ||
1495 update_info_mode || sbs->update_info_mode) {
1496 if (sbs->update_info_mode) {
1497 sbs->update_info_mode = 0;
1498 } else {
1499 sbs->update_info_mode = 1;
1501 result = acpi_battery_init(battery);
1502 if (result) {
1503 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1504 "acpi_battery_init() "
1505 "failed\n"));
1508 if (data_type == DATA_TYPE_INFO) {
1509 continue;
1512 if (sbs->zombie) {
1513 goto end;
1515 if (new_battery_present) {
1516 result = acpi_battery_get_alarm(battery);
1517 if (result) {
1518 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1519 "acpi_battery_get_alarm() "
1520 "failed\n"));
1522 if (data_type == DATA_TYPE_ALARM) {
1523 continue;
1526 result = acpi_battery_get_state(battery);
1527 if (result) {
1528 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1529 "acpi_battery_get_state() "
1530 "failed\n"));
1533 if (sbs->zombie) {
1534 goto end;
1536 if (data_type != DATA_TYPE_COMMON) {
1537 continue;
1540 if (old_battery_present != new_battery_present) {
1541 (void)sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id);
1542 result = acpi_sbs_generate_event(sbs->device,
1543 ACPI_SBS_BATTERY_NOTIFY_STATUS,
1544 new_battery_present,
1545 dir_name,
1546 ACPI_BATTERY_CLASS);
1547 if (result) {
1548 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1549 "acpi_sbs_generate_event() "
1550 "failed\n"));
1553 if (old_remaining_capacity != battery->state.remaining_capacity) {
1554 (void)sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id);
1555 result = acpi_sbs_generate_event(sbs->device,
1556 ACPI_SBS_BATTERY_NOTIFY_STATUS,
1557 new_battery_present,
1558 dir_name,
1559 ACPI_BATTERY_CLASS);
1560 if (result) {
1561 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1562 "acpi_sbs_generate_event() failed\n"));
1567 if (sbs->zombie) {
1568 goto end;
1570 if (data_type != DATA_TYPE_COMMON) {
1571 goto end;
1574 if (old_ac_present != new_ac_present) {
1575 result = acpi_sbs_generate_event(sbs->device,
1576 ACPI_SBS_AC_NOTIFY_STATUS,
1577 new_ac_present,
1578 ACPI_AC_DIR_NAME,
1579 ACPI_AC_CLASS);
1580 if (result) {
1581 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1582 "acpi_sbs_generate_event() failed\n"));
1586 end:
1587 return_VALUE(result);
1590 static void acpi_sbs_update_queue(void *data)
1592 struct acpi_sbs *sbs = data;
1593 unsigned long delay = -1;
1594 int result;
1596 ACPI_FUNCTION_TRACE("acpi_sbs_update_queue");
1598 if (sbs->zombie) {
1599 goto end;
1602 result = acpi_sbs_update_run(sbs, DATA_TYPE_COMMON);
1603 if (result) {
1604 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1605 "acpi_sbs_update_run() failed\n"));
1608 if (sbs->zombie) {
1609 goto end;
1612 if (update_mode == REQUEST_UPDATE_MODE) {
1613 goto end;
1616 delay = jiffies + HZ * update_time;
1617 sbs->update_timer.data = (unsigned long)data;
1618 sbs->update_timer.function = acpi_sbs_update_queue_run;
1619 sbs->update_timer.expires = delay;
1620 add_timer(&sbs->update_timer);
1621 end:
1625 static int acpi_sbs_add(struct acpi_device *device)
1627 struct acpi_sbs *sbs = NULL;
1628 struct acpi_ec_hc *ec_hc = NULL;
1629 int result, remove_result = 0;
1630 unsigned long sbs_obj;
1631 int id, cnt;
1632 acpi_status status = AE_OK;
1634 ACPI_FUNCTION_TRACE("acpi_sbs_add");
1636 sbs = kmalloc(sizeof(struct acpi_sbs), GFP_KERNEL);
1637 if (!sbs) {
1638 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "kmalloc() failed\n"));
1639 return_VALUE(-ENOMEM);
1641 memset(sbs, 0, sizeof(struct acpi_sbs));
1643 cnt = 0;
1644 while (cnt < 10) {
1645 cnt++;
1646 ec_hc = acpi_get_ec_hc(device);
1647 if (ec_hc) {
1648 break;
1650 msleep(1000);
1653 if (!ec_hc) {
1654 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1655 "acpi_get_ec_hc() failed: "
1656 "NO driver found for EC HC SMBus\n"));
1657 result = -ENODEV;
1658 goto end;
1661 sbs->device = device;
1662 sbs->smbus = ec_hc->smbus;
1664 strcpy(acpi_device_name(device), ACPI_SBS_DEVICE_NAME);
1665 strcpy(acpi_device_class(device), ACPI_SBS_CLASS);
1666 acpi_driver_data(device) = sbs;
1668 sbs->update_time = 0;
1669 sbs->update_time2 = 0;
1671 result = acpi_ac_add(sbs);
1672 if (result) {
1673 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "acpi_ac_add() failed\n"));
1674 goto end;
1676 result = acpi_evaluate_integer(device->handle, "_SBS", NULL, &sbs_obj);
1677 if (ACPI_FAILURE(result)) {
1678 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1679 "acpi_evaluate_integer() failed\n"));
1680 result = -EIO;
1681 goto end;
1684 if (sbs_obj > 0) {
1685 result = acpi_sbsm_get_info(sbs);
1686 if (result) {
1687 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1688 "acpi_sbsm_get_info() failed\n"));
1689 goto end;
1691 sbs->sbsm_present = 1;
1693 if (sbs->sbsm_present == 0) {
1694 result = acpi_battery_add(sbs, 0);
1695 if (result) {
1696 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1697 "acpi_battery_add() failed\n"));
1698 goto end;
1700 } else {
1701 for (id = 0; id < MAX_SBS_BAT; id++) {
1702 if ((sbs->sbsm_batteries_supported & (1 << id))) {
1703 result = acpi_battery_add(sbs, id);
1704 if (result) {
1705 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1706 "acpi_battery_add() "
1707 "failed\n"));
1708 goto end;
1714 sbs->handle = device->handle;
1716 init_timer(&sbs->update_timer);
1717 if (update_mode == QUEUE_UPDATE_MODE) {
1718 status = acpi_os_execute(OSL_GPE_HANDLER,
1719 acpi_sbs_update_queue, (void *)sbs);
1720 if (status != AE_OK) {
1721 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1722 "acpi_os_execute() failed\n"));
1725 sbs->update_time = update_time;
1726 sbs->update_time2 = update_time2;
1728 printk(KERN_INFO PREFIX "%s [%s]\n",
1729 acpi_device_name(device), acpi_device_bid(device));
1731 end:
1732 if (result) {
1733 remove_result = acpi_sbs_remove(device, 0);
1734 if (remove_result) {
1735 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1736 "acpi_sbs_remove() failed\n"));
1740 return_VALUE(result);
1743 int acpi_sbs_remove(struct acpi_device *device, int type)
1745 struct acpi_sbs *sbs = (struct acpi_sbs *)acpi_driver_data(device);
1746 int id;
1748 ACPI_FUNCTION_TRACE("acpi_sbs_remove");
1750 if (!device || !sbs) {
1751 return_VALUE(-EINVAL);
1754 sbs->zombie = 1;
1755 sbs->update_time = 0;
1756 sbs->update_time2 = 0;
1757 del_timer_sync(&sbs->update_timer);
1758 acpi_os_wait_events_complete(NULL);
1759 del_timer_sync(&sbs->update_timer);
1761 for (id = 0; id < MAX_SBS_BAT; id++) {
1762 acpi_battery_remove(sbs, id);
1765 acpi_ac_remove(sbs);
1767 kfree(sbs);
1769 return_VALUE(0);
1772 static int __init acpi_sbs_init(void)
1774 int result = 0;
1776 ACPI_FUNCTION_TRACE("acpi_sbs_init");
1778 init_MUTEX(&sbs_sem);
1780 if (capacity_mode != DEF_CAPACITY_UNIT
1781 && capacity_mode != MAH_CAPACITY_UNIT
1782 && capacity_mode != MWH_CAPACITY_UNIT) {
1783 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "acpi_sbs_init: "
1784 "invalid capacity_mode = %d\n",
1785 capacity_mode));
1786 return_VALUE(-EINVAL);
1789 acpi_ac_dir = acpi_lock_ac_dir();
1790 if (!acpi_ac_dir) {
1791 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1792 "acpi_lock_ac_dir() failed\n"));
1793 return_VALUE(-ENODEV);
1796 acpi_battery_dir = acpi_lock_battery_dir();
1797 if (!acpi_battery_dir) {
1798 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1799 "acpi_lock_battery_dir() failed\n"));
1800 return_VALUE(-ENODEV);
1803 result = acpi_bus_register_driver(&acpi_sbs_driver);
1804 if (result < 0) {
1805 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1806 "acpi_bus_register_driver() failed\n"));
1807 return_VALUE(-ENODEV);
1810 return_VALUE(0);
1813 static void __exit acpi_sbs_exit(void)
1815 ACPI_FUNCTION_TRACE("acpi_sbs_exit");
1817 acpi_bus_unregister_driver(&acpi_sbs_driver);
1819 acpi_unlock_ac_dir(acpi_ac_dir);
1820 acpi_ac_dir = NULL;
1821 acpi_unlock_battery_dir(acpi_battery_dir);
1822 acpi_battery_dir = NULL;
1824 return_VOID;
1827 module_init(acpi_sbs_init);
1828 module_exit(acpi_sbs_exit);