diff options
| author | Alexey Starikovskiy <astarikovskiy@suse.de> | 2009-10-15 06:31:44 -0400 |
|---|---|---|
| committer | Len Brown <len.brown@intel.com> | 2010-01-15 17:03:33 -0500 |
| commit | c67fcd670b55e89e0c129fbf7fae854bd1f8bfa6 (patch) | |
| tree | 3546d921cf8abc3a35bf5e771b22644fb91bf81f | |
| parent | 16698857fba1b10af4890055272975adf5686e83 (diff) | |
ACPI: Battery: Add support for _BIX extended info method
Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de>
Signed-off-by: Len Brown <len.brown@intel.com>
| -rw-r--r-- | drivers/acpi/battery.c | 68 |
1 files changed, 58 insertions, 10 deletions
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index b2b48f8545c7..1ca0ea77115b 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
| @@ -54,6 +54,7 @@ | |||
| 54 | #define ACPI_BATTERY_DEVICE_NAME "Battery" | 54 | #define ACPI_BATTERY_DEVICE_NAME "Battery" |
| 55 | #define ACPI_BATTERY_NOTIFY_STATUS 0x80 | 55 | #define ACPI_BATTERY_NOTIFY_STATUS 0x80 |
| 56 | #define ACPI_BATTERY_NOTIFY_INFO 0x81 | 56 | #define ACPI_BATTERY_NOTIFY_INFO 0x81 |
| 57 | #define ACPI_BATTERY_NOTIFY_THRESHOLD 0x82 | ||
| 57 | 58 | ||
| 58 | #define _COMPONENT ACPI_BATTERY_COMPONENT | 59 | #define _COMPONENT ACPI_BATTERY_COMPONENT |
| 59 | 60 | ||
| @@ -90,9 +91,11 @@ MODULE_DEVICE_TABLE(acpi, battery_device_ids); | |||
| 90 | 91 | ||
| 91 | enum { | 92 | enum { |
| 92 | ACPI_BATTERY_ALARM_PRESENT, | 93 | ACPI_BATTERY_ALARM_PRESENT, |
| 93 | /* For buggy DSDTs that report negative 16-bit values for either charging | 94 | ACPI_BATTERY_XINFO_PRESENT, |
| 94 | * or discharging current and/or report 0 as 65536 due to bad math. | 95 | /* For buggy DSDTs that report negative 16-bit values for either |
| 95 | */ | 96 | * charging or discharging current and/or report 0 as 65536 |
| 97 | * due to bad math. | ||
| 98 | */ | ||
| 96 | ACPI_BATTERY_QUIRK_SIGNED16_CURRENT, | 99 | ACPI_BATTERY_QUIRK_SIGNED16_CURRENT, |
| 97 | }; | 100 | }; |
| 98 | 101 | ||
| @@ -112,6 +115,12 @@ struct acpi_battery { | |||
| 112 | int design_voltage; | 115 | int design_voltage; |
| 113 | int design_capacity_warning; | 116 | int design_capacity_warning; |
| 114 | int design_capacity_low; | 117 | int design_capacity_low; |
| 118 | int cycle_count; | ||
| 119 | int measurement_accuracy; | ||
| 120 | int max_sampling_time; | ||
| 121 | int min_sampling_time; | ||
| 122 | int max_averaging_interval; | ||
| 123 | int min_averaging_interval; | ||
| 115 | int capacity_granularity_1; | 124 | int capacity_granularity_1; |
| 116 | int capacity_granularity_2; | 125 | int capacity_granularity_2; |
| 117 | int alarm; | 126 | int alarm; |
| @@ -200,6 +209,9 @@ static int acpi_battery_get_property(struct power_supply *psy, | |||
| 200 | case POWER_SUPPLY_PROP_TECHNOLOGY: | 209 | case POWER_SUPPLY_PROP_TECHNOLOGY: |
| 201 | val->intval = acpi_battery_technology(battery); | 210 | val->intval = acpi_battery_technology(battery); |
| 202 | break; | 211 | break; |
| 212 | case POWER_SUPPLY_PROP_CYCLE_COUNT: | ||
| 213 | val->intval = battery->cycle_count; | ||
| 214 | break; | ||
| 203 | case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: | 215 | case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: |
| 204 | val->intval = battery->design_voltage * 1000; | 216 | val->intval = battery->design_voltage * 1000; |
| 205 | break; | 217 | break; |
| @@ -241,6 +253,7 @@ static enum power_supply_property charge_battery_props[] = { | |||
| 241 | POWER_SUPPLY_PROP_STATUS, | 253 | POWER_SUPPLY_PROP_STATUS, |
| 242 | POWER_SUPPLY_PROP_PRESENT, | 254 | POWER_SUPPLY_PROP_PRESENT, |
| 243 | POWER_SUPPLY_PROP_TECHNOLOGY, | 255 | POWER_SUPPLY_PROP_TECHNOLOGY, |
| 256 | POWER_SUPPLY_PROP_CYCLE_COUNT, | ||
| 244 | POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, | 257 | POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, |
| 245 | POWER_SUPPLY_PROP_VOLTAGE_NOW, | 258 | POWER_SUPPLY_PROP_VOLTAGE_NOW, |
| 246 | POWER_SUPPLY_PROP_CURRENT_NOW, | 259 | POWER_SUPPLY_PROP_CURRENT_NOW, |
| @@ -256,6 +269,7 @@ static enum power_supply_property energy_battery_props[] = { | |||
| 256 | POWER_SUPPLY_PROP_STATUS, | 269 | POWER_SUPPLY_PROP_STATUS, |
| 257 | POWER_SUPPLY_PROP_PRESENT, | 270 | POWER_SUPPLY_PROP_PRESENT, |
| 258 | POWER_SUPPLY_PROP_TECHNOLOGY, | 271 | POWER_SUPPLY_PROP_TECHNOLOGY, |
| 272 | POWER_SUPPLY_PROP_CYCLE_COUNT, | ||
| 259 | POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, | 273 | POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, |
| 260 | POWER_SUPPLY_PROP_VOLTAGE_NOW, | 274 | POWER_SUPPLY_PROP_VOLTAGE_NOW, |
| 261 | POWER_SUPPLY_PROP_CURRENT_NOW, | 275 | POWER_SUPPLY_PROP_CURRENT_NOW, |
| @@ -307,6 +321,28 @@ static struct acpi_offsets info_offsets[] = { | |||
| 307 | {offsetof(struct acpi_battery, oem_info), 1}, | 321 | {offsetof(struct acpi_battery, oem_info), 1}, |
| 308 | }; | 322 | }; |
| 309 | 323 | ||
| 324 | static struct acpi_offsets extended_info_offsets[] = { | ||
| 325 | {offsetof(struct acpi_battery, power_unit), 0}, | ||
| 326 | {offsetof(struct acpi_battery, design_capacity), 0}, | ||
| 327 | {offsetof(struct acpi_battery, full_charge_capacity), 0}, | ||
| 328 | {offsetof(struct acpi_battery, technology), 0}, | ||
| 329 | {offsetof(struct acpi_battery, design_voltage), 0}, | ||
| 330 | {offsetof(struct acpi_battery, design_capacity_warning), 0}, | ||
| 331 | {offsetof(struct acpi_battery, design_capacity_low), 0}, | ||
| 332 | {offsetof(struct acpi_battery, cycle_count), 0}, | ||
| 333 | {offsetof(struct acpi_battery, measurement_accuracy), 0}, | ||
| 334 | {offsetof(struct acpi_battery, max_sampling_time), 0}, | ||
| 335 | {offsetof(struct acpi_battery, min_sampling_time), 0}, | ||
| 336 | {offsetof(struct acpi_battery, max_averaging_interval), 0}, | ||
| 337 | {offsetof(struct acpi_battery, min_averaging_interval), 0}, | ||
| 338 | {offsetof(struct acpi_battery, capacity_granularity_1), 0}, | ||
| 339 | {offsetof(struct acpi_battery, capacity_granularity_2), 0}, | ||
| 340 | {offsetof(struct acpi_battery, model_number), 1}, | ||
| 341 | {offsetof(struct acpi_battery, serial_number), 1}, | ||
| 342 | {offsetof(struct acpi_battery, type), 1}, | ||
| 343 | {offsetof(struct acpi_battery, oem_info), 1}, | ||
| 344 | }; | ||
| 345 | |||
| 310 | static int extract_package(struct acpi_battery *battery, | 346 | static int extract_package(struct acpi_battery *battery, |
| 311 | union acpi_object *package, | 347 | union acpi_object *package, |
| 312 | struct acpi_offsets *offsets, int num) | 348 | struct acpi_offsets *offsets, int num) |
| @@ -352,22 +388,29 @@ static int acpi_battery_get_info(struct acpi_battery *battery) | |||
| 352 | { | 388 | { |
| 353 | int result = -EFAULT; | 389 | int result = -EFAULT; |
| 354 | acpi_status status = 0; | 390 | acpi_status status = 0; |
| 391 | char *name = test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags)? | ||
| 392 | "_BIX" : "_BIF"; | ||
| 393 | |||
| 355 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 394 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
| 356 | 395 | ||
| 357 | if (!acpi_battery_present(battery)) | 396 | if (!acpi_battery_present(battery)) |
| 358 | return 0; | 397 | return 0; |
| 359 | mutex_lock(&battery->lock); | 398 | mutex_lock(&battery->lock); |
| 360 | status = acpi_evaluate_object(battery->device->handle, "_BIF", | 399 | status = acpi_evaluate_object(battery->device->handle, name, |
| 361 | NULL, &buffer); | 400 | NULL, &buffer); |
| 362 | mutex_unlock(&battery->lock); | 401 | mutex_unlock(&battery->lock); |
| 363 | 402 | ||
| 364 | if (ACPI_FAILURE(status)) { | 403 | if (ACPI_FAILURE(status)) { |
| 365 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF")); | 404 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating %s", name)); |
| 366 | return -ENODEV; | 405 | return -ENODEV; |
| 367 | } | 406 | } |
| 368 | 407 | if (test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags)) | |
| 369 | result = extract_package(battery, buffer.pointer, | 408 | result = extract_package(battery, buffer.pointer, |
| 370 | info_offsets, ARRAY_SIZE(info_offsets)); | 409 | extended_info_offsets, |
| 410 | ARRAY_SIZE(extended_info_offsets)); | ||
| 411 | else | ||
| 412 | result = extract_package(battery, buffer.pointer, | ||
| 413 | info_offsets, ARRAY_SIZE(info_offsets)); | ||
| 371 | kfree(buffer.pointer); | 414 | kfree(buffer.pointer); |
| 372 | return result; | 415 | return result; |
| 373 | } | 416 | } |
| @@ -414,7 +457,7 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery) | |||
| 414 | union acpi_object arg0 = { .type = ACPI_TYPE_INTEGER }; | 457 | union acpi_object arg0 = { .type = ACPI_TYPE_INTEGER }; |
| 415 | struct acpi_object_list arg_list = { 1, &arg0 }; | 458 | struct acpi_object_list arg_list = { 1, &arg0 }; |
| 416 | 459 | ||
| 417 | if (!acpi_battery_present(battery)|| | 460 | if (!acpi_battery_present(battery) || |
| 418 | !test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags)) | 461 | !test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags)) |
| 419 | return -ENODEV; | 462 | return -ENODEV; |
| 420 | 463 | ||
| @@ -592,6 +635,7 @@ static int acpi_battery_print_info(struct seq_file *seq, int result) | |||
| 592 | seq_printf(seq, "design capacity low: %d %sh\n", | 635 | seq_printf(seq, "design capacity low: %d %sh\n", |
| 593 | battery->design_capacity_low, | 636 | battery->design_capacity_low, |
| 594 | acpi_battery_units(battery)); | 637 | acpi_battery_units(battery)); |
| 638 | seq_printf(seq, "cycle count: %i\n", battery->cycle_count); | ||
| 595 | seq_printf(seq, "capacity granularity 1: %d %sh\n", | 639 | seq_printf(seq, "capacity granularity 1: %d %sh\n", |
| 596 | battery->capacity_granularity_1, | 640 | battery->capacity_granularity_1, |
| 597 | acpi_battery_units(battery)); | 641 | acpi_battery_units(battery)); |
| @@ -843,6 +887,7 @@ static int acpi_battery_add(struct acpi_device *device) | |||
| 843 | { | 887 | { |
| 844 | int result = 0; | 888 | int result = 0; |
| 845 | struct acpi_battery *battery = NULL; | 889 | struct acpi_battery *battery = NULL; |
| 890 | acpi_handle handle; | ||
| 846 | if (!device) | 891 | if (!device) |
| 847 | return -EINVAL; | 892 | return -EINVAL; |
| 848 | battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL); | 893 | battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL); |
| @@ -853,6 +898,9 @@ static int acpi_battery_add(struct acpi_device *device) | |||
| 853 | strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS); | 898 | strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS); |
| 854 | device->driver_data = battery; | 899 | device->driver_data = battery; |
| 855 | mutex_init(&battery->lock); | 900 | mutex_init(&battery->lock); |
| 901 | if (ACPI_SUCCESS(acpi_get_handle(battery->device->handle, | ||
| 902 | "_BIX", &handle))) | ||
| 903 | set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags); | ||
| 856 | acpi_battery_update(battery); | 904 | acpi_battery_update(battery); |
| 857 | #ifdef CONFIG_ACPI_PROCFS_POWER | 905 | #ifdef CONFIG_ACPI_PROCFS_POWER |
| 858 | result = acpi_battery_add_fs(device); | 906 | result = acpi_battery_add_fs(device); |
