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