Lines Matching +full:primary +full:- +full:pmic
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * battery.c - ACPI Battery Driver (Revision: 2.0)
6 * Copyright (C) 2004-2007 Vladimir Lebedev <vladimir.p.lebedev@intel.com>
78 /* Lists of PMIC ACPI HIDs with an (often better) native battery driver */
80 "INT33F4", /* X-Powers AXP288 PMIC */
92 Pre-2010 and 2012 models appear to always report in mWh and
94 and x230). Also, in mid-2012 Lenovo issued a BIOS update for
96 post-1.29 BIOS), but as of Nov. 2012, no such update is
146 return battery->device->status.battery_present; in acpi_battery_present()
151 if (!strcasecmp("NiCd", battery->type)) in acpi_battery_technology()
153 if (!strcasecmp("NiMH", battery->type)) in acpi_battery_technology()
155 if (!strcasecmp("LION", battery->type)) in acpi_battery_technology()
157 if (!strncasecmp("LI-ION", battery->type, 6)) in acpi_battery_technology()
159 if (!strcasecmp("LiP", battery->type)) in acpi_battery_technology()
169 if (battery->state != 0) in acpi_battery_is_charged()
173 if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN || in acpi_battery_is_charged()
174 battery->capacity_now == 0) in acpi_battery_is_charged()
178 if (battery->full_charge_capacity == battery->capacity_now) in acpi_battery_is_charged()
182 if (battery->design_capacity <= battery->capacity_now) in acpi_battery_is_charged()
191 return ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity) && in acpi_battery_is_degraded()
192 ACPI_BATTERY_CAPACITY_VALID(battery->design_capacity) && in acpi_battery_is_degraded()
193 battery->full_charge_capacity < battery->design_capacity; in acpi_battery_is_degraded()
204 battery->rate_now == 0) in acpi_battery_handle_discharging()
221 return -ENODEV; in acpi_battery_get_property()
224 if (battery->state & ACPI_BATTERY_STATE_DISCHARGING) in acpi_battery_get_property()
225 val->intval = acpi_battery_handle_discharging(battery); in acpi_battery_get_property()
226 else if (battery->state & ACPI_BATTERY_STATE_CHARGING) in acpi_battery_get_property()
227 val->intval = POWER_SUPPLY_STATUS_CHARGING; in acpi_battery_get_property()
229 val->intval = POWER_SUPPLY_STATUS_FULL; in acpi_battery_get_property()
231 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; in acpi_battery_get_property()
233 val->intval = POWER_SUPPLY_STATUS_UNKNOWN; in acpi_battery_get_property()
236 val->intval = acpi_battery_present(battery); in acpi_battery_get_property()
239 val->intval = acpi_battery_technology(battery); in acpi_battery_get_property()
242 val->intval = battery->cycle_count; in acpi_battery_get_property()
245 if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN) in acpi_battery_get_property()
246 ret = -ENODEV; in acpi_battery_get_property()
248 val->intval = battery->design_voltage * 1000; in acpi_battery_get_property()
251 if (battery->voltage_now == ACPI_BATTERY_VALUE_UNKNOWN) in acpi_battery_get_property()
252 ret = -ENODEV; in acpi_battery_get_property()
254 val->intval = battery->voltage_now * 1000; in acpi_battery_get_property()
258 if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN) in acpi_battery_get_property()
259 ret = -ENODEV; in acpi_battery_get_property()
261 val->intval = battery->rate_now * 1000; in acpi_battery_get_property()
265 if (!ACPI_BATTERY_CAPACITY_VALID(battery->design_capacity)) in acpi_battery_get_property()
266 ret = -ENODEV; in acpi_battery_get_property()
268 val->intval = battery->design_capacity * 1000; in acpi_battery_get_property()
272 if (!ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity)) in acpi_battery_get_property()
273 ret = -ENODEV; in acpi_battery_get_property()
275 val->intval = battery->full_charge_capacity * 1000; in acpi_battery_get_property()
279 if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN) in acpi_battery_get_property()
280 ret = -ENODEV; in acpi_battery_get_property()
282 val->intval = battery->capacity_now * 1000; in acpi_battery_get_property()
285 if (ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity)) in acpi_battery_get_property()
286 full_capacity = battery->full_charge_capacity; in acpi_battery_get_property()
287 else if (ACPI_BATTERY_CAPACITY_VALID(battery->design_capacity)) in acpi_battery_get_property()
288 full_capacity = battery->design_capacity; in acpi_battery_get_property()
290 if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN || in acpi_battery_get_property()
292 ret = -ENODEV; in acpi_battery_get_property()
294 val->intval = battery->capacity_now * 100/ in acpi_battery_get_property()
298 if (battery->state & ACPI_BATTERY_STATE_CRITICAL) in acpi_battery_get_property()
299 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL; in acpi_battery_get_property()
300 else if (test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags) && in acpi_battery_get_property()
301 (battery->capacity_now <= battery->alarm)) in acpi_battery_get_property()
302 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_LOW; in acpi_battery_get_property()
304 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_FULL; in acpi_battery_get_property()
306 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL; in acpi_battery_get_property()
309 val->strval = battery->model_number; in acpi_battery_get_property()
312 val->strval = battery->oem_info; in acpi_battery_get_property()
315 val->strval = battery->serial_number; in acpi_battery_get_property()
318 ret = -EINVAL; in acpi_battery_get_property()
387 /* --------------------------------------------------------------------------
389 -------------------------------------------------------------------------- */
447 if (package->type != ACPI_TYPE_PACKAGE) in extract_package()
448 return -EFAULT; in extract_package()
450 if (package->package.count <= i) in extract_package()
451 return -EFAULT; in extract_package()
452 element = &package->package.elements[i]; in extract_package()
455 if (element->type == ACPI_TYPE_STRING || in extract_package()
456 element->type == ACPI_TYPE_BUFFER) in extract_package()
457 strscpy(ptr, element->string.pointer, 32); in extract_package()
458 else if (element->type == ACPI_TYPE_INTEGER) { in extract_package()
459 strncpy(ptr, (u8 *)&element->integer.value, in extract_package()
466 *x = (element->type == ACPI_TYPE_INTEGER) ? in extract_package()
467 element->integer.value : -1; in extract_package()
475 if (acpi_bus_get_status(battery->device)) { in acpi_battery_get_status()
477 return -ENODEV; in acpi_battery_get_status()
487 int result = -EFAULT; in extract_battery_info()
490 result = extract_package(battery, buffer->pointer, in extract_battery_info()
492 ARRAY_SIZE(extended_info_offsets) - 1); in extract_battery_info()
494 result = extract_package(battery, buffer->pointer, in extract_battery_info()
498 result = extract_package(battery, buffer->pointer, in extract_battery_info()
500 if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags)) in extract_battery_info()
501 battery->full_charge_capacity = battery->design_capacity; in extract_battery_info()
502 if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags) && in extract_battery_info()
503 battery->power_unit && battery->design_voltage) { in extract_battery_info()
504 battery->design_capacity = battery->design_capacity * in extract_battery_info()
505 10000 / battery->design_voltage; in extract_battery_info()
506 battery->full_charge_capacity = battery->full_charge_capacity * in extract_battery_info()
507 10000 / battery->design_voltage; in extract_battery_info()
508 battery->design_capacity_warning = in extract_battery_info()
509 battery->design_capacity_warning * in extract_battery_info()
510 10000 / battery->design_voltage; in extract_battery_info()
517 if (test_bit(ACPI_BATTERY_QUIRK_DEGRADED_FULL_CHARGE, &battery->flags) && in extract_battery_info()
518 battery->capacity_now > battery->full_charge_capacity) in extract_battery_info()
519 battery->capacity_now = battery->full_charge_capacity; in extract_battery_info()
526 const int xinfo = test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags); in acpi_battery_get_info()
528 int result = -ENODEV; in acpi_battery_get_info()
534 for (use_bix = xinfo ? 1 : 0; use_bix >= 0; use_bix--) { in acpi_battery_get_info()
538 mutex_lock(&battery->lock); in acpi_battery_get_info()
539 status = acpi_evaluate_object(battery->device->handle, in acpi_battery_get_info()
542 mutex_unlock(&battery->lock); in acpi_battery_get_info()
572 if (battery->update_time && in acpi_battery_get_state()
573 time_before(jiffies, battery->update_time + in acpi_battery_get_state()
577 mutex_lock(&battery->lock); in acpi_battery_get_state()
578 status = acpi_evaluate_object(battery->device->handle, "_BST", in acpi_battery_get_state()
580 mutex_unlock(&battery->lock); in acpi_battery_get_state()
584 return -ENODEV; in acpi_battery_get_state()
589 battery->update_time = jiffies; in acpi_battery_get_state()
592 /* For buggy DSDTs that report negative 16-bit values for either in acpi_battery_get_state()
596 if (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA && in acpi_battery_get_state()
597 battery->rate_now != ACPI_BATTERY_VALUE_UNKNOWN && in acpi_battery_get_state()
598 (s16)(battery->rate_now) < 0) { in acpi_battery_get_state()
599 battery->rate_now = abs((s16)battery->rate_now); in acpi_battery_get_state()
603 if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags) in acpi_battery_get_state()
604 && battery->capacity_now >= 0 && battery->capacity_now <= 100) in acpi_battery_get_state()
605 battery->capacity_now = (battery->capacity_now * in acpi_battery_get_state()
606 battery->full_charge_capacity) / 100; in acpi_battery_get_state()
607 if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags) && in acpi_battery_get_state()
608 battery->power_unit && battery->design_voltage) { in acpi_battery_get_state()
609 battery->capacity_now = battery->capacity_now * in acpi_battery_get_state()
610 10000 / battery->design_voltage; in acpi_battery_get_state()
612 if (test_bit(ACPI_BATTERY_QUIRK_DEGRADED_FULL_CHARGE, &battery->flags) && in acpi_battery_get_state()
613 battery->capacity_now > battery->full_charge_capacity) in acpi_battery_get_state()
614 battery->capacity_now = battery->full_charge_capacity; in acpi_battery_get_state()
624 !test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags)) in acpi_battery_set_alarm()
625 return -ENODEV; in acpi_battery_set_alarm()
627 mutex_lock(&battery->lock); in acpi_battery_set_alarm()
628 status = acpi_execute_simple_method(battery->device->handle, "_BTP", in acpi_battery_set_alarm()
629 battery->alarm); in acpi_battery_set_alarm()
630 mutex_unlock(&battery->lock); in acpi_battery_set_alarm()
633 return -ENODEV; in acpi_battery_set_alarm()
635 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Alarm set to %d\n", battery->alarm)); in acpi_battery_set_alarm()
642 if (!acpi_has_method(battery->device->handle, "_BTP")) { in acpi_battery_init_alarm()
643 clear_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags); in acpi_battery_init_alarm()
646 set_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags); in acpi_battery_init_alarm()
647 if (!battery->alarm) in acpi_battery_init_alarm()
648 battery->alarm = battery->design_capacity_warning; in acpi_battery_init_alarm()
657 return sprintf(buf, "%d\n", battery->alarm * 1000); in acpi_battery_alarm_show()
667 battery->alarm = x/1000; in acpi_battery_alarm_store()
683 * platform-specific behaviour within the generic driver in a
697 * de-register all the batteries that are registered. in __battery_hook_unregister()
702 hook->remove_battery(battery->bat); in __battery_hook_unregister()
704 list_del(&hook->list); in __battery_hook_unregister()
707 pr_info("extension unregistered: %s\n", hook->name); in __battery_hook_unregister()
721 INIT_LIST_HEAD(&hook->list); in battery_hook_register()
722 list_add(&hook->list, &battery_hook_list); in battery_hook_register()
730 if (hook->add_battery(battery->bat)) { in battery_hook_register()
732 * If a add-battery returns non-zero, in battery_hook_register()
737 pr_err("extension failed to load: %s", hook->name); in battery_hook_register()
742 pr_info("new extension: %s\n", hook->name); in battery_hook_register()
758 INIT_LIST_HEAD(&battery->list); in battery_hook_add_battery()
759 list_add(&battery->list, &acpi_battery_list); in battery_hook_add_battery()
768 if (hook_node->add_battery(battery->bat)) { in battery_hook_add_battery()
774 hook_node->name); in battery_hook_add_battery()
791 hook->remove_battery(battery->bat); in battery_hook_remove_battery()
794 list_del(&battery->list); in battery_hook_remove_battery()
818 if (!ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity) && in sysfs_add_battery()
819 !ACPI_BATTERY_CAPACITY_VALID(battery->design_capacity)) in sysfs_add_battery()
822 if (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA) { in sysfs_add_battery()
824 battery->bat_desc.properties = in sysfs_add_battery()
826 battery->bat_desc.num_properties = in sysfs_add_battery()
829 battery->bat_desc.properties = charge_battery_props; in sysfs_add_battery()
830 battery->bat_desc.num_properties = in sysfs_add_battery()
835 battery->bat_desc.properties = in sysfs_add_battery()
837 battery->bat_desc.num_properties = in sysfs_add_battery()
840 battery->bat_desc.properties = energy_battery_props; in sysfs_add_battery()
841 battery->bat_desc.num_properties = in sysfs_add_battery()
846 battery->bat_desc.name = acpi_device_bid(battery->device); in sysfs_add_battery()
847 battery->bat_desc.type = POWER_SUPPLY_TYPE_BATTERY; in sysfs_add_battery()
848 battery->bat_desc.get_property = acpi_battery_get_property; in sysfs_add_battery()
850 battery->bat = power_supply_register_no_ws(&battery->device->dev, in sysfs_add_battery()
851 &battery->bat_desc, &psy_cfg); in sysfs_add_battery()
853 if (IS_ERR(battery->bat)) { in sysfs_add_battery()
854 int result = PTR_ERR(battery->bat); in sysfs_add_battery()
856 battery->bat = NULL; in sysfs_add_battery()
860 return device_create_file(&battery->bat->dev, &alarm_attr); in sysfs_add_battery()
865 mutex_lock(&battery->sysfs_lock); in sysfs_remove_battery()
866 if (!battery->bat) { in sysfs_remove_battery()
867 mutex_unlock(&battery->sysfs_lock); in sysfs_remove_battery()
871 device_remove_file(&battery->bat->dev, &alarm_attr); in sysfs_remove_battery()
872 power_supply_unregister(battery->bat); in sysfs_remove_battery()
873 battery->bat = NULL; in sysfs_remove_battery()
874 mutex_unlock(&battery->sysfs_lock); in sysfs_remove_battery()
882 if (dm->type == DMI_ENTRY_PORTABLE_BATTERY && dm->length >= 8) { in find_battery()
885 if (dm->length >= 18) in find_battery()
887 if (battery->design_capacity * battery->design_voltage / 1000 in find_battery()
889 battery->design_capacity * 10 == dmi_capacity) in find_battery()
891 &battery->flags); in find_battery()
896 * According to the ACPI spec, some kinds of primary batteries can
909 if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags)) in acpi_battery_quirks()
912 if (battery->full_charge_capacity == 100 && in acpi_battery_quirks()
913 battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN && in acpi_battery_quirks()
914 battery->capacity_now >= 0 && battery->capacity_now <= 100) { in acpi_battery_quirks()
915 set_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags); in acpi_battery_quirks()
916 battery->full_charge_capacity = battery->design_capacity; in acpi_battery_quirks()
917 battery->capacity_now = (battery->capacity_now * in acpi_battery_quirks()
918 battery->full_charge_capacity) / 100; in acpi_battery_quirks()
921 if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags)) in acpi_battery_quirks()
924 if (battery->power_unit && dmi_name_in_vendors("LENOVO")) { in acpi_battery_quirks()
930 &battery->flags) && in acpi_battery_quirks()
931 battery->design_voltage) { in acpi_battery_quirks()
932 battery->design_capacity = in acpi_battery_quirks()
933 battery->design_capacity * in acpi_battery_quirks()
934 10000 / battery->design_voltage; in acpi_battery_quirks()
935 battery->full_charge_capacity = in acpi_battery_quirks()
936 battery->full_charge_capacity * in acpi_battery_quirks()
937 10000 / battery->design_voltage; in acpi_battery_quirks()
938 battery->design_capacity_warning = in acpi_battery_quirks()
939 battery->design_capacity_warning * in acpi_battery_quirks()
940 10000 / battery->design_voltage; in acpi_battery_quirks()
941 battery->capacity_now = battery->capacity_now * in acpi_battery_quirks()
942 10000 / battery->design_voltage; in acpi_battery_quirks()
947 if (test_bit(ACPI_BATTERY_QUIRK_DEGRADED_FULL_CHARGE, &battery->flags)) in acpi_battery_quirks()
951 battery->capacity_now > battery->full_charge_capacity) { in acpi_battery_quirks()
952 set_bit(ACPI_BATTERY_QUIRK_DEGRADED_FULL_CHARGE, &battery->flags); in acpi_battery_quirks()
953 battery->capacity_now = battery->full_charge_capacity; in acpi_battery_quirks()
966 battery->update_time = 0; in acpi_battery_update()
973 if (!battery->update_time) { in acpi_battery_update()
985 if (!battery->bat) { in acpi_battery_update()
995 if ((battery->state & ACPI_BATTERY_STATE_CRITICAL) || in acpi_battery_update()
996 (test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags) && in acpi_battery_update()
997 (battery->capacity_now <= battery->alarm))) in acpi_battery_update()
998 acpi_pm_wakeup_event(&battery->device->dev); in acpi_battery_update()
1007 if (!battery->bat) in acpi_battery_refresh()
1010 power_unit = battery->power_unit; in acpi_battery_refresh()
1014 if (power_unit == battery->power_unit) in acpi_battery_refresh()
1022 /* --------------------------------------------------------------------------
1024 -------------------------------------------------------------------------- */
1033 old = battery->bat; in acpi_battery_notify()
1035 * On Acer Aspire V5-573G notifications are sometimes triggered too in acpi_battery_notify()
1045 acpi_bus_generate_netlink_event(device->pnp.device_class, in acpi_battery_notify()
1046 dev_name(&device->dev), event, in acpi_battery_notify()
1050 if (old && battery->bat) in acpi_battery_notify()
1051 power_supply_changed(battery->bat); in acpi_battery_notify()
1067 if (battery->bat) { in battery_notify()
1127 DMI_MATCH(DMI_PRODUCT_NAME, "PC-LZ750LS"),
1131 /* Acer Aspire V5-573G */
1135 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire V5-573G"),
1145 /* Above matches are too generic, add bios-date match */
1150 /* ECS EF20EA, AXP288 PMIC but uses separate fuel-gauge */
1157 /* Lenovo Ideapad Miix 320, AXP288 PMIC, separate fuel-gauge */
1162 DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 320-10ICR"),
1201 for (retry = 5; retry; retry--) { in acpi_battery_update_retry()
1217 return -EINVAL; in acpi_battery_add()
1219 if (device->dep_unmet) in acpi_battery_add()
1220 return -EPROBE_DEFER; in acpi_battery_add()
1224 return -ENOMEM; in acpi_battery_add()
1225 battery->device = device; in acpi_battery_add()
1228 device->driver_data = battery; in acpi_battery_add()
1229 mutex_init(&battery->lock); in acpi_battery_add()
1230 mutex_init(&battery->sysfs_lock); in acpi_battery_add()
1231 if (acpi_has_method(battery->device->handle, "_BIX")) in acpi_battery_add()
1232 set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags); in acpi_battery_add()
1240 device->status.battery_present ? "present" : "absent"); in acpi_battery_add()
1242 battery->pm_nb.notifier_call = battery_notify; in acpi_battery_add()
1243 register_pm_notifier(&battery->pm_nb); in acpi_battery_add()
1245 device_init_wakeup(&device->dev, 1); in acpi_battery_add()
1251 mutex_destroy(&battery->lock); in acpi_battery_add()
1252 mutex_destroy(&battery->sysfs_lock); in acpi_battery_add()
1262 return -EINVAL; in acpi_battery_remove()
1263 device_init_wakeup(&device->dev, 0); in acpi_battery_remove()
1265 unregister_pm_notifier(&battery->pm_nb); in acpi_battery_remove()
1267 mutex_destroy(&battery->lock); in acpi_battery_remove()
1268 mutex_destroy(&battery->sysfs_lock); in acpi_battery_remove()
1280 return -EINVAL; in acpi_battery_resume()
1284 return -EINVAL; in acpi_battery_resume()
1286 battery->update_time = 0; in acpi_battery_resume()
1318 if (acpi_dev_present(acpi_battery_blacklist[i], "1", -1)) { in acpi_battery_init_async()
1320 ": found native %s PMIC, not loading\n", in acpi_battery_init_async()
1333 return -ENODEV; in acpi_battery_init()