forked from Minki/linux
3e0a4e8580
Based on 1 normalized pattern(s): this program is free software you can redistribute it and or modify it under the terms of the gnu general public license as published by the free software foundation either version 2 or at your option any later version this program is distributed in the hope that it will be useful but without any warranty without even the implied warranty of merchantability or fitness for a particular purpose see the gnu general public license for more details extracted by the scancode license scanner the SPDX license identifier GPL-2.0-or-later has been chosen to replace the boilerplate/reference in 44 file(s). Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Richard Fontana <rfontana@redhat.com> Reviewed-by: Allison Randal <allison@lohutok.net> Cc: linux-spdx@vger.kernel.org Link: https://lkml.kernel.org/r/20190523091651.032047323@linutronix.de Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
109 lines
2.7 KiB
C
109 lines
2.7 KiB
C
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
/*
|
|
* APM emulation for PMU-based machines
|
|
*
|
|
* Copyright 2001 Benjamin Herrenschmidt (benh@kernel.crashing.org)
|
|
*/
|
|
|
|
#include <linux/kernel.h>
|
|
#include <linux/module.h>
|
|
#include <linux/apm-emulation.h>
|
|
#include <linux/adb.h>
|
|
#include <linux/pmu.h>
|
|
|
|
#define APM_CRITICAL 10
|
|
#define APM_LOW 30
|
|
|
|
static void pmu_apm_get_power_status(struct apm_power_info *info)
|
|
{
|
|
int percentage = -1;
|
|
int batteries = 0;
|
|
int time_units = -1;
|
|
int real_count = 0;
|
|
int i;
|
|
char charging = 0;
|
|
long charge = -1;
|
|
long amperage = 0;
|
|
unsigned long btype = 0;
|
|
|
|
info->battery_status = APM_BATTERY_STATUS_UNKNOWN;
|
|
info->battery_flag = APM_BATTERY_FLAG_UNKNOWN;
|
|
info->units = APM_UNITS_MINS;
|
|
|
|
if (pmu_power_flags & PMU_PWR_AC_PRESENT)
|
|
info->ac_line_status = APM_AC_ONLINE;
|
|
else
|
|
info->ac_line_status = APM_AC_OFFLINE;
|
|
|
|
for (i=0; i<pmu_battery_count; i++) {
|
|
if (pmu_batteries[i].flags & PMU_BATT_PRESENT) {
|
|
batteries++;
|
|
if (percentage < 0)
|
|
percentage = 0;
|
|
if (charge < 0)
|
|
charge = 0;
|
|
percentage += (pmu_batteries[i].charge * 100) /
|
|
pmu_batteries[i].max_charge;
|
|
charge += pmu_batteries[i].charge;
|
|
amperage += pmu_batteries[i].amperage;
|
|
if (btype == 0)
|
|
btype = (pmu_batteries[i].flags & PMU_BATT_TYPE_MASK);
|
|
real_count++;
|
|
if ((pmu_batteries[i].flags & PMU_BATT_CHARGING))
|
|
charging++;
|
|
}
|
|
}
|
|
if (batteries == 0)
|
|
info->ac_line_status = APM_AC_ONLINE;
|
|
|
|
if (real_count) {
|
|
if (amperage < 0) {
|
|
if (btype == PMU_BATT_TYPE_SMART)
|
|
time_units = (charge * 59) / (amperage * -1);
|
|
else
|
|
time_units = (charge * 16440) / (amperage * -60);
|
|
}
|
|
percentage /= real_count;
|
|
if (charging > 0) {
|
|
info->battery_status = APM_BATTERY_STATUS_CHARGING;
|
|
info->battery_flag = APM_BATTERY_FLAG_CHARGING;
|
|
} else if (percentage <= APM_CRITICAL) {
|
|
info->battery_status = APM_BATTERY_STATUS_CRITICAL;
|
|
info->battery_flag = APM_BATTERY_FLAG_CRITICAL;
|
|
} else if (percentage <= APM_LOW) {
|
|
info->battery_status = APM_BATTERY_STATUS_LOW;
|
|
info->battery_flag = APM_BATTERY_FLAG_LOW;
|
|
} else {
|
|
info->battery_status = APM_BATTERY_STATUS_HIGH;
|
|
info->battery_flag = APM_BATTERY_FLAG_HIGH;
|
|
}
|
|
}
|
|
|
|
info->battery_life = percentage;
|
|
info->time = time_units;
|
|
}
|
|
|
|
static int __init apm_emu_init(void)
|
|
{
|
|
apm_get_power_status = pmu_apm_get_power_status;
|
|
|
|
printk(KERN_INFO "apm_emu: PMU APM Emulation initialized.\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void __exit apm_emu_exit(void)
|
|
{
|
|
if (apm_get_power_status == pmu_apm_get_power_status)
|
|
apm_get_power_status = NULL;
|
|
|
|
printk(KERN_INFO "apm_emu: PMU APM Emulation removed.\n");
|
|
}
|
|
|
|
module_init(apm_emu_init);
|
|
module_exit(apm_emu_exit);
|
|
|
|
MODULE_AUTHOR("Benjamin Herrenschmidt");
|
|
MODULE_DESCRIPTION("APM emulation for PowerMac");
|
|
MODULE_LICENSE("GPL");
|