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