1 /* 2 * sbs.c - ACPI Smart Battery System Driver ($Revision: 2.0 $) 3 * 4 * Copyright (c) 2007 Alexey Starikovskiy <astarikovskiy@suse.de> 5 * Copyright (c) 2005-2007 Vladimir Lebedev <vladimir.p.lebedev@intel.com> 6 * Copyright (c) 2005 Rich Townsend <rhdt@bartol.udel.edu> 7 * 8 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or (at 13 * your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, but 16 * WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 * General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License along 21 * with this program; if not, write to the Free Software Foundation, Inc., 22 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 23 * 24 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 25 */ 26 27 #include <linux/init.h> 28 #include <linux/module.h> 29 #include <linux/moduleparam.h> 30 #include <linux/kernel.h> 31 32 #ifdef CONFIG_ACPI_PROCFS 33 #include <linux/proc_fs.h> 34 #include <linux/seq_file.h> 35 #include <asm/uaccess.h> 36 #endif 37 38 #include <linux/acpi.h> 39 #include <linux/timer.h> 40 #include <linux/jiffies.h> 41 #include <linux/delay.h> 42 43 #include <linux/power_supply.h> 44 45 #include "sbshc.h" 46 47 #define ACPI_SBS_CLASS "sbs" 48 #define ACPI_AC_CLASS "ac_adapter" 49 #define ACPI_BATTERY_CLASS "battery" 50 #define ACPI_SBS_DEVICE_NAME "Smart Battery System" 51 #define ACPI_SBS_FILE_INFO "info" 52 #define ACPI_SBS_FILE_STATE "state" 53 #define ACPI_SBS_FILE_ALARM "alarm" 54 #define ACPI_BATTERY_DIR_NAME "BAT%i" 55 #define ACPI_AC_DIR_NAME "AC0" 56 57 enum acpi_sbs_device_addr { 58 ACPI_SBS_CHARGER = 0x9, 59 ACPI_SBS_MANAGER = 0xa, 60 ACPI_SBS_BATTERY = 0xb, 61 }; 62 63 #define ACPI_SBS_NOTIFY_STATUS 0x80 64 #define ACPI_SBS_NOTIFY_INFO 0x81 65 66 MODULE_AUTHOR("Alexey Starikovskiy <astarikovskiy@suse.de>"); 67 MODULE_DESCRIPTION("Smart Battery System ACPI interface driver"); 68 MODULE_LICENSE("GPL"); 69 70 static unsigned int cache_time = 1000; 71 module_param(cache_time, uint, 0644); 72 MODULE_PARM_DESC(cache_time, "cache time in milliseconds"); 73 74 extern struct proc_dir_entry *acpi_lock_ac_dir(void); 75 extern struct proc_dir_entry *acpi_lock_battery_dir(void); 76 extern void acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir); 77 extern void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir); 78 79 #define MAX_SBS_BAT 4 80 #define ACPI_SBS_BLOCK_MAX 32 81 82 static const struct acpi_device_id sbs_device_ids[] = { 83 {"ACPI0002", 0}, 84 {"", 0}, 85 }; 86 MODULE_DEVICE_TABLE(acpi, sbs_device_ids); 87 88 struct acpi_battery { 89 struct power_supply bat; 90 struct acpi_sbs *sbs; 91 #ifdef CONFIG_ACPI_PROCFS 92 struct proc_dir_entry *proc_entry; 93 #endif 94 unsigned long update_time; 95 char name[8]; 96 char manufacturer_name[ACPI_SBS_BLOCK_MAX]; 97 char device_name[ACPI_SBS_BLOCK_MAX]; 98 char device_chemistry[ACPI_SBS_BLOCK_MAX]; 99 u16 alarm_capacity; 100 u16 full_charge_capacity; 101 u16 design_capacity; 102 u16 design_voltage; 103 u16 serial_number; 104 u16 cycle_count; 105 u16 temp_now; 106 u16 voltage_now; 107 s16 current_now; 108 s16 current_avg; 109 u16 capacity_now; 110 u16 state_of_charge; 111 u16 state; 112 u16 mode; 113 u16 spec; 114 u8 id; 115 u8 present:1; 116 }; 117 118 #define to_acpi_battery(x) container_of(x, struct acpi_battery, bat); 119 120 struct acpi_sbs { 121 struct power_supply charger; 122 struct acpi_device *device; 123 struct acpi_smb_hc *hc; 124 struct mutex lock; 125 #ifdef CONFIG_ACPI_PROCFS 126 struct proc_dir_entry *charger_entry; 127 #endif 128 struct acpi_battery battery[MAX_SBS_BAT]; 129 u8 batteries_supported:4; 130 u8 manager_present:1; 131 u8 charger_present:1; 132 }; 133 134 #define to_acpi_sbs(x) container_of(x, struct acpi_sbs, charger) 135 136 static inline int battery_scale(int log) 137 { 138 int scale = 1; 139 while (log--) 140 scale *= 10; 141 return scale; 142 } 143 144 static inline int acpi_battery_vscale(struct acpi_battery *battery) 145 { 146 return battery_scale((battery->spec & 0x0f00) >> 8); 147 } 148 149 static inline int acpi_battery_ipscale(struct acpi_battery *battery) 150 { 151 return battery_scale((battery->spec & 0xf000) >> 12); 152 } 153 154 static inline int acpi_battery_mode(struct acpi_battery *battery) 155 { 156 return (battery->mode & 0x8000); 157 } 158 159 static inline int acpi_battery_scale(struct acpi_battery *battery) 160 { 161 return (acpi_battery_mode(battery) ? 10 : 1) * 162 acpi_battery_ipscale(battery); 163 } 164 165 static int sbs_get_ac_property(struct power_supply *psy, 166 enum power_supply_property psp, 167 union power_supply_propval *val) 168 { 169 struct acpi_sbs *sbs = to_acpi_sbs(psy); 170 switch (psp) { 171 case POWER_SUPPLY_PROP_ONLINE: 172 val->intval = sbs->charger_present; 173 break; 174 default: 175 return -EINVAL; 176 } 177 return 0; 178 } 179 180 static int acpi_battery_technology(struct acpi_battery *battery) 181 { 182 if (!strcasecmp("NiCd", battery->device_chemistry)) 183 return POWER_SUPPLY_TECHNOLOGY_NiCd; 184 if (!strcasecmp("NiMH", battery->device_chemistry)) 185 return POWER_SUPPLY_TECHNOLOGY_NiMH; 186 if (!strcasecmp("LION", battery->device_chemistry)) 187 return POWER_SUPPLY_TECHNOLOGY_LION; 188 if (!strcasecmp("LiP", battery->device_chemistry)) 189 return POWER_SUPPLY_TECHNOLOGY_LIPO; 190 return POWER_SUPPLY_TECHNOLOGY_UNKNOWN; 191 } 192 193 static int acpi_sbs_battery_get_property(struct power_supply *psy, 194 enum power_supply_property psp, 195 union power_supply_propval *val) 196 { 197 struct acpi_battery *battery = to_acpi_battery(psy); 198 199 if ((!battery->present) && psp != POWER_SUPPLY_PROP_PRESENT) 200 return -ENODEV; 201 switch (psp) { 202 case POWER_SUPPLY_PROP_STATUS: 203 if (battery->current_now < 0) 204 val->intval = POWER_SUPPLY_STATUS_DISCHARGING; 205 else if (battery->current_now > 0) 206 val->intval = POWER_SUPPLY_STATUS_CHARGING; 207 else 208 val->intval = POWER_SUPPLY_STATUS_FULL; 209 break; 210 case POWER_SUPPLY_PROP_PRESENT: 211 val->intval = battery->present; 212 break; 213 case POWER_SUPPLY_PROP_TECHNOLOGY: 214 val->intval = acpi_battery_technology(battery); 215 break; 216 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: 217 val->intval = battery->design_voltage * 218 acpi_battery_vscale(battery) * 1000; 219 break; 220 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 221 val->intval = battery->voltage_now * 222 acpi_battery_vscale(battery) * 1000; 223 break; 224 case POWER_SUPPLY_PROP_CURRENT_NOW: 225 val->intval = abs(battery->current_now) * 226 acpi_battery_ipscale(battery) * 1000; 227 break; 228 case POWER_SUPPLY_PROP_CURRENT_AVG: 229 val->intval = abs(battery->current_avg) * 230 acpi_battery_ipscale(battery) * 1000; 231 break; 232 case POWER_SUPPLY_PROP_CAPACITY: 233 val->intval = battery->state_of_charge; 234 break; 235 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: 236 case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN: 237 val->intval = battery->design_capacity * 238 acpi_battery_scale(battery) * 1000; 239 break; 240 case POWER_SUPPLY_PROP_CHARGE_FULL: 241 case POWER_SUPPLY_PROP_ENERGY_FULL: 242 val->intval = battery->full_charge_capacity * 243 acpi_battery_scale(battery) * 1000; 244 break; 245 case POWER_SUPPLY_PROP_CHARGE_NOW: 246 case POWER_SUPPLY_PROP_ENERGY_NOW: 247 val->intval = battery->capacity_now * 248 acpi_battery_scale(battery) * 1000; 249 break; 250 case POWER_SUPPLY_PROP_TEMP: 251 val->intval = battery->temp_now - 2730; // dK -> dC 252 break; 253 case POWER_SUPPLY_PROP_MODEL_NAME: 254 val->strval = battery->device_name; 255 break; 256 case POWER_SUPPLY_PROP_MANUFACTURER: 257 val->strval = battery->manufacturer_name; 258 break; 259 default: 260 return -EINVAL; 261 } 262 return 0; 263 } 264 265 static enum power_supply_property sbs_ac_props[] = { 266 POWER_SUPPLY_PROP_ONLINE, 267 }; 268 269 static enum power_supply_property sbs_charge_battery_props[] = { 270 POWER_SUPPLY_PROP_STATUS, 271 POWER_SUPPLY_PROP_PRESENT, 272 POWER_SUPPLY_PROP_TECHNOLOGY, 273 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, 274 POWER_SUPPLY_PROP_VOLTAGE_NOW, 275 POWER_SUPPLY_PROP_CURRENT_NOW, 276 POWER_SUPPLY_PROP_CURRENT_AVG, 277 POWER_SUPPLY_PROP_CAPACITY, 278 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, 279 POWER_SUPPLY_PROP_CHARGE_FULL, 280 POWER_SUPPLY_PROP_CHARGE_NOW, 281 POWER_SUPPLY_PROP_TEMP, 282 POWER_SUPPLY_PROP_MODEL_NAME, 283 POWER_SUPPLY_PROP_MANUFACTURER, 284 }; 285 286 static enum power_supply_property sbs_energy_battery_props[] = { 287 POWER_SUPPLY_PROP_STATUS, 288 POWER_SUPPLY_PROP_PRESENT, 289 POWER_SUPPLY_PROP_TECHNOLOGY, 290 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, 291 POWER_SUPPLY_PROP_VOLTAGE_NOW, 292 POWER_SUPPLY_PROP_CURRENT_NOW, 293 POWER_SUPPLY_PROP_CURRENT_AVG, 294 POWER_SUPPLY_PROP_CAPACITY, 295 POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN, 296 POWER_SUPPLY_PROP_ENERGY_FULL, 297 POWER_SUPPLY_PROP_ENERGY_NOW, 298 POWER_SUPPLY_PROP_TEMP, 299 POWER_SUPPLY_PROP_MODEL_NAME, 300 POWER_SUPPLY_PROP_MANUFACTURER, 301 }; 302 303 /* -------------------------------------------------------------------------- 304 Smart Battery System Management 305 -------------------------------------------------------------------------- */ 306 307 struct acpi_battery_reader { 308 u8 command; /* command for battery */ 309 u8 mode; /* word or block? */ 310 size_t offset; /* offset inside struct acpi_sbs_battery */ 311 }; 312 313 static struct acpi_battery_reader info_readers[] = { 314 {0x01, SMBUS_READ_WORD, offsetof(struct acpi_battery, alarm_capacity)}, 315 {0x03, SMBUS_READ_WORD, offsetof(struct acpi_battery, mode)}, 316 {0x10, SMBUS_READ_WORD, offsetof(struct acpi_battery, full_charge_capacity)}, 317 {0x17, SMBUS_READ_WORD, offsetof(struct acpi_battery, cycle_count)}, 318 {0x18, SMBUS_READ_WORD, offsetof(struct acpi_battery, design_capacity)}, 319 {0x19, SMBUS_READ_WORD, offsetof(struct acpi_battery, design_voltage)}, 320 {0x1a, SMBUS_READ_WORD, offsetof(struct acpi_battery, spec)}, 321 {0x1c, SMBUS_READ_WORD, offsetof(struct acpi_battery, serial_number)}, 322 {0x20, SMBUS_READ_BLOCK, offsetof(struct acpi_battery, manufacturer_name)}, 323 {0x21, SMBUS_READ_BLOCK, offsetof(struct acpi_battery, device_name)}, 324 {0x22, SMBUS_READ_BLOCK, offsetof(struct acpi_battery, device_chemistry)}, 325 }; 326 327 static struct acpi_battery_reader state_readers[] = { 328 {0x08, SMBUS_READ_WORD, offsetof(struct acpi_battery, temp_now)}, 329 {0x09, SMBUS_READ_WORD, offsetof(struct acpi_battery, voltage_now)}, 330 {0x0a, SMBUS_READ_WORD, offsetof(struct acpi_battery, current_now)}, 331 {0x0b, SMBUS_READ_WORD, offsetof(struct acpi_battery, current_avg)}, 332 {0x0f, SMBUS_READ_WORD, offsetof(struct acpi_battery, capacity_now)}, 333 {0x0e, SMBUS_READ_WORD, offsetof(struct acpi_battery, state_of_charge)}, 334 {0x16, SMBUS_READ_WORD, offsetof(struct acpi_battery, state)}, 335 }; 336 337 static int acpi_manager_get_info(struct acpi_sbs *sbs) 338 { 339 int result = 0; 340 u16 battery_system_info; 341 342 result = acpi_smbus_read(sbs->hc, SMBUS_READ_WORD, ACPI_SBS_MANAGER, 343 0x04, (u8 *)&battery_system_info); 344 if (!result) 345 sbs->batteries_supported = battery_system_info & 0x000f; 346 return result; 347 } 348 349 static int acpi_battery_get_info(struct acpi_battery *battery) 350 { 351 int i, result = 0; 352 353 for (i = 0; i < ARRAY_SIZE(info_readers); ++i) { 354 result = acpi_smbus_read(battery->sbs->hc, 355 info_readers[i].mode, 356 ACPI_SBS_BATTERY, 357 info_readers[i].command, 358 (u8 *) battery + 359 info_readers[i].offset); 360 if (result) 361 break; 362 } 363 return result; 364 } 365 366 static int acpi_battery_get_state(struct acpi_battery *battery) 367 { 368 int i, result = 0; 369 370 if (battery->update_time && 371 time_before(jiffies, battery->update_time + 372 msecs_to_jiffies(cache_time))) 373 return 0; 374 for (i = 0; i < ARRAY_SIZE(state_readers); ++i) { 375 result = acpi_smbus_read(battery->sbs->hc, 376 state_readers[i].mode, 377 ACPI_SBS_BATTERY, 378 state_readers[i].command, 379 (u8 *)battery + 380 state_readers[i].offset); 381 if (result) 382 goto end; 383 } 384 end: 385 battery->update_time = jiffies; 386 return result; 387 } 388 389 static int acpi_battery_get_alarm(struct acpi_battery *battery) 390 { 391 return acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, 392 ACPI_SBS_BATTERY, 0x01, 393 (u8 *)&battery->alarm_capacity); 394 } 395 396 static int acpi_battery_set_alarm(struct acpi_battery *battery) 397 { 398 struct acpi_sbs *sbs = battery->sbs; 399 u16 value, sel = 1 << (battery->id + 12); 400 401 int ret; 402 403 404 if (sbs->manager_present) { 405 ret = acpi_smbus_read(sbs->hc, SMBUS_READ_WORD, ACPI_SBS_MANAGER, 406 0x01, (u8 *)&value); 407 if (ret) 408 goto end; 409 if ((value & 0xf000) != sel) { 410 value &= 0x0fff; 411 value |= sel; 412 ret = acpi_smbus_write(sbs->hc, SMBUS_WRITE_WORD, 413 ACPI_SBS_MANAGER, 414 0x01, (u8 *)&value, 2); 415 if (ret) 416 goto end; 417 } 418 } 419 ret = acpi_smbus_write(sbs->hc, SMBUS_WRITE_WORD, ACPI_SBS_BATTERY, 420 0x01, (u8 *)&battery->alarm_capacity, 2); 421 end: 422 return ret; 423 } 424 425 static int acpi_ac_get_present(struct acpi_sbs *sbs) 426 { 427 int result; 428 u16 status; 429 430 result = acpi_smbus_read(sbs->hc, SMBUS_READ_WORD, ACPI_SBS_CHARGER, 431 0x13, (u8 *) & status); 432 if (!result) 433 sbs->charger_present = (status >> 15) & 0x1; 434 return result; 435 } 436 437 static ssize_t acpi_battery_alarm_show(struct device *dev, 438 struct device_attribute *attr, 439 char *buf) 440 { 441 struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev)); 442 acpi_battery_get_alarm(battery); 443 return sprintf(buf, "%d\n", battery->alarm_capacity * 444 acpi_battery_scale(battery) * 1000); 445 } 446 447 static ssize_t acpi_battery_alarm_store(struct device *dev, 448 struct device_attribute *attr, 449 const char *buf, size_t count) 450 { 451 unsigned long x; 452 struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev)); 453 if (sscanf(buf, "%ld\n", &x) == 1) 454 battery->alarm_capacity = x / 455 (1000 * acpi_battery_scale(battery)); 456 if (battery->present) 457 acpi_battery_set_alarm(battery); 458 return count; 459 } 460 461 static struct device_attribute alarm_attr = { 462 .attr = {.name = "alarm", .mode = 0644, .owner = THIS_MODULE}, 463 .show = acpi_battery_alarm_show, 464 .store = acpi_battery_alarm_store, 465 }; 466 467 /* -------------------------------------------------------------------------- 468 FS Interface (/proc/acpi) 469 -------------------------------------------------------------------------- */ 470 471 #ifdef CONFIG_ACPI_PROCFS 472 /* Generic Routines */ 473 static int 474 acpi_sbs_add_fs(struct proc_dir_entry **dir, 475 struct proc_dir_entry *parent_dir, 476 char *dir_name, 477 struct file_operations *info_fops, 478 struct file_operations *state_fops, 479 struct file_operations *alarm_fops, void *data) 480 { 481 struct proc_dir_entry *entry = NULL; 482 483 if (!*dir) { 484 *dir = proc_mkdir(dir_name, parent_dir); 485 if (!*dir) { 486 return -ENODEV; 487 } 488 (*dir)->owner = THIS_MODULE; 489 } 490 491 /* 'info' [R] */ 492 if (info_fops) { 493 entry = create_proc_entry(ACPI_SBS_FILE_INFO, S_IRUGO, *dir); 494 if (entry) { 495 entry->proc_fops = info_fops; 496 entry->data = data; 497 entry->owner = THIS_MODULE; 498 } 499 } 500 501 /* 'state' [R] */ 502 if (state_fops) { 503 entry = create_proc_entry(ACPI_SBS_FILE_STATE, S_IRUGO, *dir); 504 if (entry) { 505 entry->proc_fops = state_fops; 506 entry->data = data; 507 entry->owner = THIS_MODULE; 508 } 509 } 510 511 /* 'alarm' [R/W] */ 512 if (alarm_fops) { 513 entry = create_proc_entry(ACPI_SBS_FILE_ALARM, S_IRUGO, *dir); 514 if (entry) { 515 entry->proc_fops = alarm_fops; 516 entry->data = data; 517 entry->owner = THIS_MODULE; 518 } 519 } 520 return 0; 521 } 522 523 static void 524 acpi_sbs_remove_fs(struct proc_dir_entry **dir, 525 struct proc_dir_entry *parent_dir) 526 { 527 if (*dir) { 528 remove_proc_entry(ACPI_SBS_FILE_INFO, *dir); 529 remove_proc_entry(ACPI_SBS_FILE_STATE, *dir); 530 remove_proc_entry(ACPI_SBS_FILE_ALARM, *dir); 531 remove_proc_entry((*dir)->name, parent_dir); 532 *dir = NULL; 533 } 534 } 535 536 /* Smart Battery Interface */ 537 static struct proc_dir_entry *acpi_battery_dir = NULL; 538 539 static inline char *acpi_battery_units(struct acpi_battery *battery) 540 { 541 return acpi_battery_mode(battery) ? " mWh" : " mAh"; 542 } 543 544 545 static int acpi_battery_read_info(struct seq_file *seq, void *offset) 546 { 547 struct acpi_battery *battery = seq->private; 548 struct acpi_sbs *sbs = battery->sbs; 549 int result = 0; 550 551 mutex_lock(&sbs->lock); 552 553 seq_printf(seq, "present: %s\n", 554 (battery->present) ? "yes" : "no"); 555 if (!battery->present) 556 goto end; 557 558 seq_printf(seq, "design capacity: %i%s\n", 559 battery->design_capacity * acpi_battery_scale(battery), 560 acpi_battery_units(battery)); 561 seq_printf(seq, "last full capacity: %i%s\n", 562 battery->full_charge_capacity * acpi_battery_scale(battery), 563 acpi_battery_units(battery)); 564 seq_printf(seq, "battery technology: rechargeable\n"); 565 seq_printf(seq, "design voltage: %i mV\n", 566 battery->design_voltage * acpi_battery_vscale(battery)); 567 seq_printf(seq, "design capacity warning: unknown\n"); 568 seq_printf(seq, "design capacity low: unknown\n"); 569 seq_printf(seq, "capacity granularity 1: unknown\n"); 570 seq_printf(seq, "capacity granularity 2: unknown\n"); 571 seq_printf(seq, "model number: %s\n", battery->device_name); 572 seq_printf(seq, "serial number: %i\n", 573 battery->serial_number); 574 seq_printf(seq, "battery type: %s\n", 575 battery->device_chemistry); 576 seq_printf(seq, "OEM info: %s\n", 577 battery->manufacturer_name); 578 end: 579 mutex_unlock(&sbs->lock); 580 return result; 581 } 582 583 static int acpi_battery_info_open_fs(struct inode *inode, struct file *file) 584 { 585 return single_open(file, acpi_battery_read_info, PDE(inode)->data); 586 } 587 588 static int acpi_battery_read_state(struct seq_file *seq, void *offset) 589 { 590 struct acpi_battery *battery = seq->private; 591 struct acpi_sbs *sbs = battery->sbs; 592 int result = 0; 593 594 mutex_lock(&sbs->lock); 595 seq_printf(seq, "present: %s\n", 596 (battery->present) ? "yes" : "no"); 597 if (!battery->present) 598 goto end; 599 600 acpi_battery_get_state(battery); 601 seq_printf(seq, "capacity state: %s\n", 602 (battery->state & 0x0010) ? "critical" : "ok"); 603 seq_printf(seq, "charging state: %s\n", 604 (battery->current_now < 0) ? "discharging" : 605 ((battery->current_now > 0) ? "charging" : "charged")); 606 seq_printf(seq, "present rate: %d mA\n", 607 abs(battery->current_now) * acpi_battery_ipscale(battery)); 608 seq_printf(seq, "remaining capacity: %i%s\n", 609 battery->capacity_now * acpi_battery_scale(battery), 610 acpi_battery_units(battery)); 611 seq_printf(seq, "present voltage: %i mV\n", 612 battery->voltage_now * acpi_battery_vscale(battery)); 613 614 end: 615 mutex_unlock(&sbs->lock); 616 return result; 617 } 618 619 static int acpi_battery_state_open_fs(struct inode *inode, struct file *file) 620 { 621 return single_open(file, acpi_battery_read_state, PDE(inode)->data); 622 } 623 624 static int acpi_battery_read_alarm(struct seq_file *seq, void *offset) 625 { 626 struct acpi_battery *battery = seq->private; 627 struct acpi_sbs *sbs = battery->sbs; 628 int result = 0; 629 630 mutex_lock(&sbs->lock); 631 632 if (!battery->present) { 633 seq_printf(seq, "present: no\n"); 634 goto end; 635 } 636 637 acpi_battery_get_alarm(battery); 638 seq_printf(seq, "alarm: "); 639 if (battery->alarm_capacity) 640 seq_printf(seq, "%i%s\n", 641 battery->alarm_capacity * 642 acpi_battery_scale(battery), 643 acpi_battery_units(battery)); 644 else 645 seq_printf(seq, "disabled\n"); 646 end: 647 mutex_unlock(&sbs->lock); 648 return result; 649 } 650 651 static ssize_t 652 acpi_battery_write_alarm(struct file *file, const char __user * buffer, 653 size_t count, loff_t * ppos) 654 { 655 struct seq_file *seq = file->private_data; 656 struct acpi_battery *battery = seq->private; 657 struct acpi_sbs *sbs = battery->sbs; 658 char alarm_string[12] = { '\0' }; 659 int result = 0; 660 mutex_lock(&sbs->lock); 661 if (!battery->present) { 662 result = -ENODEV; 663 goto end; 664 } 665 if (count > sizeof(alarm_string) - 1) { 666 result = -EINVAL; 667 goto end; 668 } 669 if (copy_from_user(alarm_string, buffer, count)) { 670 result = -EFAULT; 671 goto end; 672 } 673 alarm_string[count] = 0; 674 battery->alarm_capacity = simple_strtoul(alarm_string, NULL, 0) / 675 acpi_battery_scale(battery); 676 acpi_battery_set_alarm(battery); 677 end: 678 mutex_unlock(&sbs->lock); 679 if (result) 680 return result; 681 return count; 682 } 683 684 static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file) 685 { 686 return single_open(file, acpi_battery_read_alarm, PDE(inode)->data); 687 } 688 689 static struct file_operations acpi_battery_info_fops = { 690 .open = acpi_battery_info_open_fs, 691 .read = seq_read, 692 .llseek = seq_lseek, 693 .release = single_release, 694 .owner = THIS_MODULE, 695 }; 696 697 static struct file_operations acpi_battery_state_fops = { 698 .open = acpi_battery_state_open_fs, 699 .read = seq_read, 700 .llseek = seq_lseek, 701 .release = single_release, 702 .owner = THIS_MODULE, 703 }; 704 705 static struct file_operations acpi_battery_alarm_fops = { 706 .open = acpi_battery_alarm_open_fs, 707 .read = seq_read, 708 .write = acpi_battery_write_alarm, 709 .llseek = seq_lseek, 710 .release = single_release, 711 .owner = THIS_MODULE, 712 }; 713 714 /* Legacy AC Adapter Interface */ 715 716 static struct proc_dir_entry *acpi_ac_dir = NULL; 717 718 static int acpi_ac_read_state(struct seq_file *seq, void *offset) 719 { 720 721 struct acpi_sbs *sbs = seq->private; 722 723 mutex_lock(&sbs->lock); 724 725 seq_printf(seq, "state: %s\n", 726 sbs->charger_present ? "on-line" : "off-line"); 727 728 mutex_unlock(&sbs->lock); 729 return 0; 730 } 731 732 static int acpi_ac_state_open_fs(struct inode *inode, struct file *file) 733 { 734 return single_open(file, acpi_ac_read_state, PDE(inode)->data); 735 } 736 737 static struct file_operations acpi_ac_state_fops = { 738 .open = acpi_ac_state_open_fs, 739 .read = seq_read, 740 .llseek = seq_lseek, 741 .release = single_release, 742 .owner = THIS_MODULE, 743 }; 744 745 #endif 746 747 /* -------------------------------------------------------------------------- 748 Driver Interface 749 -------------------------------------------------------------------------- */ 750 static int acpi_battery_read(struct acpi_battery *battery) 751 { 752 int result = 0, saved_present = battery->present; 753 u16 state; 754 755 if (battery->sbs->manager_present) { 756 result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, 757 ACPI_SBS_MANAGER, 0x01, (u8 *)&state); 758 if (!result) 759 battery->present = state & (1 << battery->id); 760 state &= 0x0fff; 761 state |= 1 << (battery->id + 12); 762 acpi_smbus_write(battery->sbs->hc, SMBUS_WRITE_WORD, 763 ACPI_SBS_MANAGER, 0x01, (u8 *)&state, 2); 764 } else if (battery->id == 0) 765 battery->present = 1; 766 if (result || !battery->present) 767 return result; 768 769 if (saved_present != battery->present) { 770 battery->update_time = 0; 771 result = acpi_battery_get_info(battery); 772 if (result) 773 return result; 774 } 775 result = acpi_battery_get_state(battery); 776 return result; 777 } 778 779 /* Smart Battery */ 780 static int acpi_battery_add(struct acpi_sbs *sbs, int id) 781 { 782 struct acpi_battery *battery = &sbs->battery[id]; 783 int result; 784 785 battery->id = id; 786 battery->sbs = sbs; 787 result = acpi_battery_read(battery); 788 if (result) 789 return result; 790 791 sprintf(battery->name, ACPI_BATTERY_DIR_NAME, id); 792 #ifdef CONFIG_ACPI_PROCFS 793 acpi_sbs_add_fs(&battery->proc_entry, acpi_battery_dir, 794 battery->name, &acpi_battery_info_fops, 795 &acpi_battery_state_fops, &acpi_battery_alarm_fops, 796 battery); 797 #endif 798 battery->bat.name = battery->name; 799 battery->bat.type = POWER_SUPPLY_TYPE_BATTERY; 800 if (!acpi_battery_mode(battery)) { 801 battery->bat.properties = sbs_charge_battery_props; 802 battery->bat.num_properties = 803 ARRAY_SIZE(sbs_charge_battery_props); 804 } else { 805 battery->bat.properties = sbs_energy_battery_props; 806 battery->bat.num_properties = 807 ARRAY_SIZE(sbs_energy_battery_props); 808 } 809 battery->bat.get_property = acpi_sbs_battery_get_property; 810 result = power_supply_register(&sbs->device->dev, &battery->bat); 811 device_create_file(battery->bat.dev, &alarm_attr); 812 printk(KERN_INFO PREFIX "%s [%s]: Battery Slot [%s] (battery %s)\n", 813 ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device), 814 battery->name, sbs->battery->present ? "present" : "absent"); 815 return result; 816 } 817 818 static void acpi_battery_remove(struct acpi_sbs *sbs, int id) 819 { 820 if (sbs->battery[id].bat.dev) 821 device_remove_file(sbs->battery[id].bat.dev, &alarm_attr); 822 power_supply_unregister(&sbs->battery[id].bat); 823 #ifdef CONFIG_ACPI_PROCFS 824 if (sbs->battery[id].proc_entry) { 825 acpi_sbs_remove_fs(&(sbs->battery[id].proc_entry), 826 acpi_battery_dir); 827 } 828 #endif 829 } 830 831 static int acpi_charger_add(struct acpi_sbs *sbs) 832 { 833 int result; 834 835 result = acpi_ac_get_present(sbs); 836 if (result) 837 goto end; 838 #ifdef CONFIG_ACPI_PROCFS 839 result = acpi_sbs_add_fs(&sbs->charger_entry, acpi_ac_dir, 840 ACPI_AC_DIR_NAME, NULL, 841 &acpi_ac_state_fops, NULL, sbs); 842 if (result) 843 goto end; 844 #endif 845 sbs->charger.name = "sbs-charger"; 846 sbs->charger.type = POWER_SUPPLY_TYPE_MAINS; 847 sbs->charger.properties = sbs_ac_props; 848 sbs->charger.num_properties = ARRAY_SIZE(sbs_ac_props); 849 sbs->charger.get_property = sbs_get_ac_property; 850 power_supply_register(&sbs->device->dev, &sbs->charger); 851 printk(KERN_INFO PREFIX "%s [%s]: AC Adapter [%s] (%s)\n", 852 ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device), 853 ACPI_AC_DIR_NAME, sbs->charger_present ? "on-line" : "off-line"); 854 end: 855 return result; 856 } 857 858 static void acpi_charger_remove(struct acpi_sbs *sbs) 859 { 860 if (sbs->charger.dev) 861 power_supply_unregister(&sbs->charger); 862 #ifdef CONFIG_ACPI_PROCFS 863 if (sbs->charger_entry) 864 acpi_sbs_remove_fs(&sbs->charger_entry, acpi_ac_dir); 865 #endif 866 } 867 868 void acpi_sbs_callback(void *context) 869 { 870 int id; 871 struct acpi_sbs *sbs = context; 872 struct acpi_battery *bat; 873 u8 saved_charger_state = sbs->charger_present; 874 u8 saved_battery_state; 875 acpi_ac_get_present(sbs); 876 if (sbs->charger_present != saved_charger_state) { 877 #ifdef CONFIG_ACPI_PROC_EVENT 878 acpi_bus_generate_proc_event4(ACPI_AC_CLASS, ACPI_AC_DIR_NAME, 879 ACPI_SBS_NOTIFY_STATUS, 880 sbs->charger_present); 881 #endif 882 kobject_uevent(&sbs->charger.dev->kobj, KOBJ_CHANGE); 883 } 884 if (sbs->manager_present) { 885 for (id = 0; id < MAX_SBS_BAT; ++id) { 886 if (!(sbs->batteries_supported & (1 << id))) 887 continue; 888 bat = &sbs->battery[id]; 889 saved_battery_state = bat->present; 890 acpi_battery_read(bat); 891 if (saved_battery_state == bat->present) 892 continue; 893 #ifdef CONFIG_ACPI_PROC_EVENT 894 acpi_bus_generate_proc_event4(ACPI_BATTERY_CLASS, 895 bat->name, 896 ACPI_SBS_NOTIFY_STATUS, 897 bat->present); 898 #endif 899 kobject_uevent(&bat->bat.dev->kobj, KOBJ_CHANGE); 900 } 901 } 902 } 903 904 static int acpi_sbs_remove(struct acpi_device *device, int type); 905 906 static int acpi_sbs_add(struct acpi_device *device) 907 { 908 struct acpi_sbs *sbs; 909 int result = 0; 910 int id; 911 912 sbs = kzalloc(sizeof(struct acpi_sbs), GFP_KERNEL); 913 if (!sbs) { 914 result = -ENOMEM; 915 goto end; 916 } 917 918 mutex_init(&sbs->lock); 919 920 sbs->hc = acpi_driver_data(device->parent); 921 sbs->device = device; 922 strcpy(acpi_device_name(device), ACPI_SBS_DEVICE_NAME); 923 strcpy(acpi_device_class(device), ACPI_SBS_CLASS); 924 acpi_driver_data(device) = sbs; 925 926 result = acpi_charger_add(sbs); 927 if (result) 928 goto end; 929 930 result = acpi_manager_get_info(sbs); 931 if (!result) { 932 sbs->manager_present = 1; 933 for (id = 0; id < MAX_SBS_BAT; ++id) 934 if ((sbs->batteries_supported & (1 << id))) 935 acpi_battery_add(sbs, id); 936 } else 937 acpi_battery_add(sbs, 0); 938 acpi_smbus_register_callback(sbs->hc, acpi_sbs_callback, sbs); 939 end: 940 if (result) 941 acpi_sbs_remove(device, 0); 942 return result; 943 } 944 945 static int acpi_sbs_remove(struct acpi_device *device, int type) 946 { 947 struct acpi_sbs *sbs; 948 int id; 949 950 if (!device) 951 return -EINVAL; 952 sbs = acpi_driver_data(device); 953 if (!sbs) 954 return -EINVAL; 955 mutex_lock(&sbs->lock); 956 acpi_smbus_unregister_callback(sbs->hc); 957 for (id = 0; id < MAX_SBS_BAT; ++id) 958 acpi_battery_remove(sbs, id); 959 acpi_charger_remove(sbs); 960 mutex_unlock(&sbs->lock); 961 mutex_destroy(&sbs->lock); 962 kfree(sbs); 963 return 0; 964 } 965 966 static void acpi_sbs_rmdirs(void) 967 { 968 #ifdef CONFIG_ACPI_PROCFS 969 if (acpi_ac_dir) { 970 acpi_unlock_ac_dir(acpi_ac_dir); 971 acpi_ac_dir = NULL; 972 } 973 if (acpi_battery_dir) { 974 acpi_unlock_battery_dir(acpi_battery_dir); 975 acpi_battery_dir = NULL; 976 } 977 #endif 978 } 979 980 static int acpi_sbs_resume(struct acpi_device *device) 981 { 982 struct acpi_sbs *sbs; 983 if (!device) 984 return -EINVAL; 985 sbs = device->driver_data; 986 acpi_sbs_callback(sbs); 987 return 0; 988 } 989 990 static struct acpi_driver acpi_sbs_driver = { 991 .name = "sbs", 992 .class = ACPI_SBS_CLASS, 993 .ids = sbs_device_ids, 994 .ops = { 995 .add = acpi_sbs_add, 996 .remove = acpi_sbs_remove, 997 .resume = acpi_sbs_resume, 998 }, 999 }; 1000 1001 static int __init acpi_sbs_init(void) 1002 { 1003 int result = 0; 1004 1005 if (acpi_disabled) 1006 return -ENODEV; 1007 #ifdef CONFIG_ACPI_PROCFS 1008 acpi_ac_dir = acpi_lock_ac_dir(); 1009 if (!acpi_ac_dir) 1010 return -ENODEV; 1011 acpi_battery_dir = acpi_lock_battery_dir(); 1012 if (!acpi_battery_dir) { 1013 acpi_sbs_rmdirs(); 1014 return -ENODEV; 1015 } 1016 #endif 1017 result = acpi_bus_register_driver(&acpi_sbs_driver); 1018 if (result < 0) { 1019 acpi_sbs_rmdirs(); 1020 return -ENODEV; 1021 } 1022 return 0; 1023 } 1024 1025 static void __exit acpi_sbs_exit(void) 1026 { 1027 acpi_bus_unregister_driver(&acpi_sbs_driver); 1028 acpi_sbs_rmdirs(); 1029 return; 1030 } 1031 1032 module_init(acpi_sbs_init); 1033 module_exit(acpi_sbs_exit); 1034