// SPDX-License-Identifier: GPL-2.0-or-later
/*
* battery.c - ACPI Battery Driver (Revision: 2.0)
*
* Copyright (C) 2007 Alexey Starikovskiy <astarikovskiy@suse.de>
* Copyright (C) 2004-2007 Vladimir Lebedev <vladimir.p.lebedev@intel.com>
* Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
* Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/async.h>
#include <linux/delay.h>
#include <linux/dmi.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/suspend.h>
#include <linux/types.h>
#include <asm/unaligned.h>
#include <linux/acpi.h>
#include <linux/power_supply.h>
#include <acpi/battery.h>
#define PREFIX "ACPI: "
#define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF
#define ACPI_BATTERY_CAPACITY_VALID(capacity) \
((capacity) != 0 && (capacity) != ACPI_BATTERY_VALUE_UNKNOWN)
#define ACPI_BATTERY_DEVICE_NAME "Battery"
/* Battery power unit: 0 means mW, 1 means mA */
#define ACPI_BATTERY_POWER_UNIT_MA 1
#define ACPI_BATTERY_STATE_DISCHARGING 0x1
#define ACPI_BATTERY_STATE_CHARGING 0x2
#define ACPI_BATTERY_STATE_CRITICAL 0x4
#define _COMPONENT ACPI_BATTERY_COMPONENT
ACPI_MODULE_NAME("battery");
MODULE_AUTHOR("Paul Diefenbaugh");
MODULE_AUTHOR("Alexey Starikovskiy <astarikovskiy@suse.de>");
MODULE_DESCRIPTION("ACPI Battery Driver");
MODULE_LICENSE("GPL");
static async_cookie_t async_cookie;
static bool battery_driver_registered;
static int battery_bix_broken_package;
static int battery_notification_delay_ms;
static int battery_ac_is_broken;
static int battery_check_pmic = 1;
static unsigned int cache_time = 1000;
module_param(cache_time, uint, 0644);
MODULE_PARM_DESC(cache_time, "cache time in milliseconds");
static const struct acpi_device_id battery_device_ids[] = {
{"PNP0C0A", 0},
{"", 0},
};
MODULE_DEVICE_TABLE(acpi, battery_device_ids);
/* Lists of PMIC ACPI HIDs with an (often better) native battery driver */
static const char * const acpi_battery_blacklist[] = {
"INT33F4", /* X-Powers AXP288 PMIC */
};
enum {
ACPI_BATTERY_ALARM_PRESENT,
ACPI_BATTERY_XINFO_PRESENT,
ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY,
/* On Lenovo Thinkpad models from 2010 and 2011, the power unit
switches between mWh and mAh depending on whether the system
is running on battery or not. When mAh is the unit, most
reported values are incorrect and need to be adjusted by
10000/design_voltage. Verified on x201, t410, t410s, and x220.
Pre-2010 and 2012 models appear to always report in mWh and
are thus unaffected (tested with t42, t61, t500, x200, x300,
and x230). Also, in mid-2012 Lenovo issued a BIOS update for
the 2011 models that fixes the issue (tested on x220 with a
post-1.29 BIOS), but as of Nov. 2012, no such update is
available for the 2010 models. */
ACPI_BATTERY_QUIRK_THINKPAD_MAH,
/* for batteries reporting current capacity with design capacity
* on a full charge, but showing degradation in full charge cap.
*/
ACPI_BATTERY_QUIRK_DEGRADED_FULL_CHARGE,
};
struct acpi_battery {
struct mutex lock;
struct mutex sysfs_lock;
struct power_supply *bat;
struct power_supply_desc bat_desc;
struct acpi_device *device;
struct notifier_block pm_nb;
struct list_head list;
unsigned long update_time;
int revision;
int rate_now;
int capacity_now;
int <