This patch enables powertop to display power estimates on devices that
implement power_supply class and donot have acpi battery interface.
First the sysfs/power_class interface is checked and if it is not accesible
the acpi/battery interface is used
---
Makefile | 2 +-
measurement/measurement.cpp | 40 ++++++++-
measurement/power_supply.cpp | 184 ++++++++++++++++++++++++++++++++++++++++++
measurement/power_supply.h | 46 +++++++++++
4 files changed, 267 insertions(+), 5 deletions(-)
create mode 100755 measurement/power_supply.cpp
create mode 100755 measurement/power_supply.h
diff --git a/Makefile b/Makefile
index b0b6cb7..f0ebf21 100644
--- a/Makefile
+++ b/Makefile
@@ -13,7 +13,7 @@ OBJS += perf/perf.o perf/perf_bundle.o
OBJS += process/process.o process/do_process.o process/interrupt.o
process/timer.o process/work.o process/powerconsumer.o process/device.o
DEVS += devices/device.o devices/backlight.o devices/usb.o devices/ahci.o
devices/alsa.o devices/rfkill.o devices/i915-gpu.o devices/thinkpad-fan.o
devices/network.o devices/thinkpad-light.o
DEVS += devices/runtime_pm.o
-DEVS += measurement/measurement.o measurement/acpi.o measurement/extech.o
+DEVS += measurement/measurement.o measurement/acpi.o measurement/extech.o
measurement/power_supply.o
OBJS += $(DEVS)
OBJS += parameters/parameters.o parameters/learn.o parameters/persistent.o
OBJS += calibrate/calibrate.o
diff --git a/measurement/measurement.cpp b/measurement/measurement.cpp
index 3dbaab9..0d679f7 100644
--- a/measurement/measurement.cpp
+++ b/measurement/measurement.cpp
@@ -25,11 +25,14 @@
#include "measurement.h"
#include "acpi.h"
#include "extech.h"
+#include "power_supply.h"
#include "../parameters/parameters.h"
#include "../lib.h"
#include <sys/types.h>
#include <dirent.h>
+#include <stdio.h>
+#include <fstream>
double min_power = 50000.0;
@@ -111,16 +114,45 @@ void power_meters_callback(const char *d_name)
power_meters.push_back(meter);
}
+void power_supply_callback(const char *d_name)
+{
+ char filename[4096];
+ char line[4096];
+ ifstream file;
+ bool discharging = false;
+
+ sprintf(filename, "/sys/class/power_supply/%s/uevent", d_name);
+ file.open(filename, ios::in);
+ if (!file)
+ return;
+
+ while (file) {
+ file.getline(line, 4096);
+
+ if (strstr(line, "POWER_SUPPLY_STATUS") && strstr(line,
"POWER_SUPPLY_STATUS"))
+ discharging = true;
+ }
+ file.close();
+
+ if (!discharging)
+ return;
+
+ class power_supply *power;
+ power = new(std::nothrow) class power_supply(d_name);
+ if (power)
+ power_meters.push_back(power);
+}
+
void detect_power_meters(void)
{
- process_directory("/proc/acpi/battery", power_meters_callback);
+ if (access("/sys/class/power_supply", R_OK ) == 0)
+ process_directory("/sys/class/power_supply",
power_supply_callback);
+ else if (access("/proc/acpi/battery", R_OK ) == 0)
+ process_directory("/proc/acpi/battery", power_meters_callback);
}
void extech_power_meter(const char *devnode)
{
- DIR *dir;
- struct dirent *entry;
-
class extech_power_meter *meter;
meter = new class extech_power_meter(devnode);
diff --git a/measurement/power_supply.cpp b/measurement/power_supply.cpp
new file mode 100755
index 0000000..b4fe3af
--- /dev/null
+++ b/measurement/power_supply.cpp
@@ -0,0 +1,184 @@
+/*
+ * Copyright 2011, Intel Corporation
+ *
+ * This file is part of PowerTOP
+ *
+ * This program file 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; version 2 of the License.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program in a file named COPYING; if not, write to the
+ * Free Software Foundation, Inc,
+ * 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ * or just google for it.
+ *
+ * Authors:
+ * John Mathew <[email protected]>
+ */
+#include "measurement.h"
+#include "power_supply.h"
+#include <iostream>
+#include <fstream>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+using namespace std;
+
+power_supply::power_supply(const char *supply_name)
+{
+ rate = 0.0;
+ capacity = 0.0;
+ voltage = 0.0;
+ strncpy(battery_name, supply_name, sizeof(battery_name));
+}
+
+/*
+POWER_SUPPLY_NAME=msic-battery
+POWER_SUPPLY_STATUS=Discharging
+POWER_SUPPLY_HEALTH=Cold
+POWER_SUPPLY_PRESENT=1
+POWER_SUPPLY_TECHNOLOGY=Li-ion
+POWER_SUPPLY_VOLTAGE_MAX_DESIGN=4200000
+POWER_SUPPLY_VOLTAGE_NOW=4119000
+POWER_SUPPLY_CURRENT_NOW=-290000
+POWER_SUPPLY_CHARGE_NOW=1503000
+POWER_SUPPLY_CHARGE_COUNTER=-254923
+POWER_SUPPLY_CHARGE_FULL_DESIGN=1500000
+POWER_SUPPLY_CHARGE_FULL=1500000
+POWER_SUPPLY_CHARGE_AVG=32762000
+POWER_SUPPLY_ENERGY_FULL=6300000
+POWER_SUPPLY_ENERGY_NOW=6235000
+POWER_SUPPLY_CAPACITY_LEVEL=Full
+POWER_SUPPLY_CAPACITY=100
+POWER_SUPPLY_TEMP=-340
+POWER_SUPPLY_MODEL_NAME=CDK0
+POWER_SUPPLY_MANUFACTURER=IN
+
+Quoting include/linux/power_supply.h:
+
+All voltages, currents, charges, energies, time and temperatures in µV,
+µA, µAh, µWh, seconds and tenths of degree Celsius unless otherwise
+stated. It's driver's job to convert its raw values to units in which
+this class operates.
+*/
+
+void power_supply::measure(void)
+{
+ char filename[4096];
+ char line[4096];
+ ifstream file;
+
+ double _rate = 0;
+ double _capacity = 0;
+ double _voltage = 0;
+
+ char rate_units[16];
+ char capacity_units[16];
+ char voltage_units[16];
+
+ rate_units[0] = 0;
+ capacity_units[0] = 0;
+ voltage_units[0] = 0;
+
+ rate = 0;
+ voltage = 0;
+ capacity = 0;
+
+ sprintf(filename, "/sys/class/power_supply/%s/uevent", battery_name);
+
+ file.open(filename, ios::in);
+ if (!file)
+ return;
+
+ while (file) {
+ char *c;
+ file.getline(line, 4096);
+
+ if (strstr(line, "PRESENT")) {
+ c = strchr(line, '=');
+ c++;
+ if(*c == '0'){
+ printf ("Battery not present");
+ return;
+ }
+ }
+ if (strstr(line, "CURRENT_NOW")) {
+ c = strchr(line, '=');
+ c++;
+ if(*c == '-') c++; // ignoring the negative sign
+ _rate = strtoull(c, NULL, 10);
+ if (c) {
+ //printf ("CURRENT: %f. \n",_rate);
+ } else {
+ _rate = 0;
+ }
+ }
+ if (strstr(line, "CAPACITY=")) {
+ c = strchr(line, '=');
+ c++;
+ _capacity = strtoull(c, NULL, 10);
+ if (c) {
+ //printf ("CAPACITY: %f. \n",_capacity);
+ } else {
+ _capacity = 0;
+ }
+ }
+ if (strstr(line, "VOLTAGE_NOW")) {
+ c = strchr(line, '=');
+ c++;
+ while (*c == ' ') c++;
+ _voltage = strtoull(c, NULL, 10);
+ if (c) {
+ //printf ("VOLTAGE_NOW: %f. \n",_voltage);
+ } else {
+ _voltage = 0;
+ }
+ }
+ }
+ file.close();
+
+ if(_voltage) {
+ _voltage = _voltage / 1000.0;
+ voltage = _voltage;
+ } else {
+ voltage = 0.0;
+ }
+
+ if(_rate) {
+ _rate = _rate / 1000.0;
+ _rate = _rate * _voltage;
+ rate = _rate;
+ } else {
+ rate = 0.0;
+ }
+
+ if(_capacity)
+ capacity = _capacity;
+ else
+ capacity = 0.0;
+}
+
+
+void power_supply::end_measurement(void)
+{
+ measure();
+}
+
+void power_supply::start_measurement(void)
+{
+ /* ACPI battery state is a lagging indication, lets only measure at the
end */
+}
+
+
+double power_supply::joules_consumed(void)
+{
+ return rate;
+}
diff --git a/measurement/power_supply.h b/measurement/power_supply.h
new file mode 100755
index 0000000..5ad776e
--- /dev/null
+++ b/measurement/power_supply.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2011, Intel Corporation
+ *
+ * This file is part of PowerTOP
+ *
+ * This program file 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; version 2 of the License.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program in a file named COPYING; if not, write to the
+ * Free Software Foundation, Inc,
+ * 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ * or just google for it.
+ *
+ * Authors:
+ * John Mathew <[email protected]>
+ */
+#ifndef __INCLUDE_GUARD_POWER_SUPPLY_H
+#define __INCLUDE_GUARD_POWER_SUPPLY_H
+
+#include "measurement.h"
+
+class power_supply:public power_meter {
+ char battery_name[256];
+
+ double capacity;
+ double rate;
+ double voltage;
+ void measure(void);
+public:
+ power_supply(const char *_battery_name);
+ virtual void start_measurement(void);
+ virtual void end_measurement(void);
+
+ virtual double joules_consumed(void);
+ virtual double dev_capacity(void) { return capacity; };
+};
+
+#endif
--
1.7.0.4
---------------------------------------------------------------------
Intel Corporation SAS (French simplified joint stock company)
Registered headquarters: "Les Montalets"- 2, rue de Paris,
92196 Meudon Cedex, France
Registration Number: 302 456 199 R.C.S. NANTERRE
Capital: 4,572,000 Euros
This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.
_______________________________________________
Power mailing list
[email protected]
https://bughost.org/mailman/listinfo/power