import of tp-smapi version 0.37

This commit is contained in:
Shem Multinymous 2008-01-27 23:39:27 +01:00 committed by Evgeni Golov
parent e84c5799e2
commit 6cb5f3e763
5 changed files with 138 additions and 64 deletions

13
CHANGES
View File

@ -1,5 +1,18 @@
Change history for tp_smapi:
0.37 2008-03-28
---------------------
- Fix compilation on kernel 2.6.25
- hdaps whitelist: changed default orientation of ThinkPad R60, R61, X40, X41.
- tp_smapi: Added 3 new read-only battery attributes
/sys/devices/platform/smapi/BAT?/remaining_running_time_now
(time remaining according to instantenous power instead of average)
/sys/devices/platform/smapi/BAT?/charging_max_current
(maximum current allowed during charging)
/sys/devices/platform/smapi/BAT?/charging_max_voltage
(maximum voltage allowed during charging)
- tp_smapi and README: improved documentation of battery info attributes.
0.36 2008-01-27
---------------------
- tp_smapi: Added a 4th cell group voltage attribute:

59
README
View File

@ -1,4 +1,4 @@
tp_smapi version 0.36
tp_smapi version 0.37
IBM ThinkPad hardware functions driver
Author: Shem Multinymous <multinymous@gmail.com>
@ -105,34 +105,37 @@ Forcing battery discharging even if AC power available:
(This can be used to control which battery is discharged when using an
Ultrabay battery.)
Misc read-only battery status (see note about HDAPS below):
Misc read-only battery status attributes (see note about HDAPS below):
# cat /sys/devices/platform/smapi/BAT0/installed
# cat /sys/devices/platform/smapi/BAT0/state # idle/charging/discharging
# cat /sys/devices/platform/smapi/BAT0/cycle_count
# cat /sys/devices/platform/smapi/BAT0/current_now # instantaneous current
# cat /sys/devices/platform/smapi/BAT0/current_avg # last minute average
# cat /sys/devices/platform/smapi/BAT0/power_now # instantaneous power
# cat /sys/devices/platform/smapi/BAT0/power_avg # last minute average
# cat /sys/devices/platform/smapi/BAT0/last_full_capacity
# cat /sys/devices/platform/smapi/BAT0/remaining_percent
# cat /sys/devices/platform/smapi/BAT0/remaining_running_time
# cat /sys/devices/platform/smapi/BAT0/remaining_charging_time
# cat /sys/devices/platform/smapi/BAT0/remaining_capacity
# cat /sys/devices/platform/smapi/BAT0/design_capacity
# cat /sys/devices/platform/smapi/BAT0/voltage
# cat /sys/devices/platform/smapi/BAT0/design_voltage
# cat /sys/devices/platform/smapi/BAT0/group{0,1,2,3}_voltage # see below
# cat /sys/devices/platform/smapi/BAT0/manufacturer
# cat /sys/devices/platform/smapi/BAT0/model
# cat /sys/devices/platform/smapi/BAT0/barcoding
# cat /sys/devices/platform/smapi/BAT0/chemistry
# cat /sys/devices/platform/smapi/BAT0/serial
# cat /sys/devices/platform/smapi/BAT0/manufacture_date
# cat /sys/devices/platform/smapi/BAT0/first_use_date
# cat /sys/devices/platform/smapi/BAT0/temperature # in milli-Celsius
# cat /sys/devices/platform/smapi/ac_connected
# cat /sys/devices/platform/smapi/BAT0/dump # see below
/sys/devices/platform/smapi/BAT0/installed # 0 or 1
/sys/devices/platform/smapi/BAT0/state # idle/charging/discharging
/sys/devices/platform/smapi/BAT0/cycle_count # integer counter
/sys/devices/platform/smapi/BAT0/current_now # instantaneous current
/sys/devices/platform/smapi/BAT0/current_avg # last minute average
/sys/devices/platform/smapi/BAT0/power_now # instantaneous power
/sys/devices/platform/smapi/BAT0/power_avg # last minute average
/sys/devices/platform/smapi/BAT0/last_full_capacity # in mWh
/sys/devices/platform/smapi/BAT0/remaining_percent # remaining percent of energy
/sys/devices/platform/smapi/BAT0/remaining_running_time # in minutes, by last minute average power
/sys/devices/platform/smapi/BAT0/remaining_running_time_now # in minutes, by instantenous power
/sys/devices/platform/smapi/BAT0/remaining_charging_time # in minutes
/sys/devices/platform/smapi/BAT0/remaining_capacity # in mWh
/sys/devices/platform/smapi/BAT0/design_capacity # in mWh
/sys/devices/platform/smapi/BAT0/voltage # in mV
/sys/devices/platform/smapi/BAT0/design_voltage # in mV
/sys/devices/platform/smapi/BAT0/charging_max_current # max charging current
/sys/devices/platform/smapi/BAT0/charging_max_voltage # max charging voltage
/sys/devices/platform/smapi/BAT0/group{0,1,2,3}_voltage # see below
/sys/devices/platform/smapi/BAT0/manufacturer # string
/sys/devices/platform/smapi/BAT0/model # string
/sys/devices/platform/smapi/BAT0/barcoding # string
/sys/devices/platform/smapi/BAT0/chemistry # string
/sys/devices/platform/smapi/BAT0/serial # integer
/sys/devices/platform/smapi/BAT0/manufacture_date # YYYY-MM-DD
/sys/devices/platform/smapi/BAT0/first_use_date # YYYY-MM-DD
/sys/devices/platform/smapi/BAT0/temperature # in milli-Celsius
/sys/devices/platform/smapi/BAT0/dump # see below
/sys/devices/platform/smapi/ac_connected # 0 or 1
The BAT0/group{0,1,2,3}_voltage attribute refers to the separate cell groups
in each battery. For example, on the ThinkPad 600, X3x, T4x and R5x models,

11
hdaps.c
View File

@ -36,6 +36,7 @@
#include <linux/jiffies.h>
#include <linux/thinkpad_ec.h>
#include <linux/pci_ids.h>
#include <linux/version.h>
/* Embedded controller accelerometer read command and its result: */
static const struct thinkpad_ec_row ec_accel_args =
@ -789,10 +790,12 @@ struct dmi_system_id __initdata hdaps_whitelist[] = {
HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad R60", HDAPS_ORIENT_INVERT_XY),
HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T41p", HDAPS_ORIENT_INVERT_XY),
HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T42p", HDAPS_ORIENT_INVERT_XY),
HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad X40", HDAPS_ORIENT_INVERT_Y),
HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad X41", HDAPS_ORIENT_INVERT_Y),
HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad R60", HDAPS_ORIENT_INVERT_XY),
HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad R61", HDAPS_ORIENT_INVERT_XY),
HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T60", HDAPS_ORIENT_INVERT_XY),
HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T61", HDAPS_ORIENT_INVERT_XY),
HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X40", HDAPS_ORIENT_INVERT_Y),
HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X41", HDAPS_ORIENT_INVERT_Y),
HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X60 Tablet", HDAPS_ORIENT_INVERT_Y),
HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X60s", HDAPS_ORIENT_INVERT_Y),
HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X60", HDAPS_ORIENT_SWAP | HDAPS_ORIENT_INVERT_X),
@ -848,7 +851,9 @@ static int __init hdaps_init(void)
hdaps_idev->id.vendor = HDAPS_INPUT_VENDOR;
hdaps_idev->id.product = HDAPS_INPUT_PRODUCT;
hdaps_idev->id.version = HDAPS_INPUT_JS_VERSION;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
hdaps_idev->cdev.dev = &pdev->dev;
#endif
hdaps_idev->evbit[0] = BIT(EV_ABS);
hdaps_idev->open = hdaps_mousedev_open;
hdaps_idev->close = hdaps_mousedev_close;
@ -868,7 +873,9 @@ static int __init hdaps_init(void)
hdaps_idev_raw->id.vendor = HDAPS_INPUT_VENDOR;
hdaps_idev_raw->id.product = HDAPS_INPUT_PRODUCT;
hdaps_idev_raw->id.version = HDAPS_INPUT_RAW_VERSION;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
hdaps_idev_raw->cdev.dev = &pdev->dev;
#endif
hdaps_idev_raw->evbit[0] = BIT(EV_ABS);
hdaps_idev_raw->open = hdaps_mousedev_open;
hdaps_idev_raw->close = hdaps_mousedev_close;

View File

@ -1,15 +1,16 @@
/*
* thinkpad_ec.c - coordinate access to ThinkPad-specific hardware resources
* thinkpad_ec.c - ThinkPad embedded controller LPC3 functions
*
* The embedded controller on ThinkPad laptops has a non-standard interface
* at IO ports 0x1600-0x161F (mapped to LCP channel 3 of the H8S chip).
* The interface provides various system management services (currently
* The embedded controller on ThinkPad laptops has a non-standard interface,
* where LPC channel 3 of the H8S EC chip is hooked up to IO ports
* 0x1600-0x161F and implements (a special case of) the H8S LPC protocol.
* The EC LPC interface provides various system management services (currently
* known: battery information and accelerometer readouts). This driver
* provides access and mutual exclusion for the EC interface.
*
* The LPC protocol and terminology is documented here:
* "H8S/2104B Group Hardware Manual",
* http://documentation.renesas.com/eng/products/mpumcu/rej09b0300_2140bhm.pdf
* http://documentation.renesas.com/eng/products/mpumcu/rej09b0300_2140bhm.pdf
*
* Copyright (C) 2006-2007 Shem Multinymous <multinymous@gmail.com>
*
@ -38,7 +39,7 @@
#include <asm/semaphore.h>
#include <asm/io.h>
#define TP_VERSION "0.36"
#define TP_VERSION "0.37"
MODULE_AUTHOR("Shem Multinymous");
MODULE_DESCRIPTION("ThinkPad embedded controller hardware access");

View File

@ -9,6 +9,10 @@
* It also exposes battery status information, obtained from the ThinkPad
* embedded controller (via the thinkpad_ec module).
*
* Many of the battery status values obtained from the EC simply mirror
* values provided by the battery's Smart Battery System (SBS) interface, so
* their meaning is defined by the Smart Battery Data Specification.
* References to this SBS spec are given in the code where relevant.
*
* Copyright (C) 2006 Shem Multinymous <multinymous@gmail.com>.
* SMAPI access code based on the mwave driver by Mike Sullivan.
@ -41,7 +45,7 @@
#include <asm/uaccess.h>
#include <asm/io.h>
#define TP_VERSION "0.36"
#define TP_VERSION "0.37"
#define TP_DESC "ThinkPad SMAPI Support"
#define TP_DIR "smapi"
@ -685,7 +689,7 @@ static ssize_t show_tp_ec_bat_power(u8 arg0, int offV, int offI,
return ret;
millivolt = *(u16 *)(row+offV);
milliamp = *(s16 *)(row+offI);
return sprintf(buf, "%d\n", milliamp*millivolt/1000); /* type: mW */
return sprintf(buf, "%d\n", milliamp*millivolt/1000); /* units: mW */
}
/**
@ -732,7 +736,7 @@ static ssize_t show_battery_start_charge_thresh(struct device *dev,
int ret = get_thresh(bat, THRESH_START, &thresh);
if (ret)
return ret;
return sprintf(buf, "%d\n", thresh); /* type: percent */
return sprintf(buf, "%d\n", thresh); /* units: percent */
}
static ssize_t show_battery_stop_charge_thresh(struct device *dev,
@ -743,7 +747,7 @@ static ssize_t show_battery_stop_charge_thresh(struct device *dev,
int ret = get_thresh(bat, THRESH_STOP, &thresh);
if (ret)
return ret;
return sprintf(buf, "%d\n", thresh); /* type: percent */
return sprintf(buf, "%d\n", thresh); /* units: percent */
}
/**
@ -840,7 +844,7 @@ static ssize_t show_battery_inhibit_charge_minutes(struct device *dev,
int ret = get_inhibit_charge_minutes(bat, &minutes);
if (ret)
return ret;
return sprintf(buf, "%d\n", minutes); /* type: minutes */
return sprintf(buf, "%d\n", minutes); /* units: minutes */
}
static ssize_t store_battery_inhibit_charge_minutes(struct device *dev,
@ -920,154 +924,197 @@ static ssize_t show_battery_state(
static ssize_t show_battery_manufacturer(
struct device *dev, struct device_attribute *attr, char *buf)
{
/* type: string. SBS spec v1.1 p34: ManufacturerName() */
return show_tp_ec_bat_str(4, 2, TP_CONTROLLER_ROW_LEN-2, attr, buf);
}
static ssize_t show_battery_model(
struct device *dev, struct device_attribute *attr, char *buf)
{
/* type: string. SBS spec v1.1 p34: DeviceName() */
return show_tp_ec_bat_str(5, 2, TP_CONTROLLER_ROW_LEN-2, attr, buf);
}
static ssize_t show_battery_barcoding(
struct device *dev, struct device_attribute *attr, char *buf)
{
/* type: string */
return show_tp_ec_bat_str(7, 2, TP_CONTROLLER_ROW_LEN-2, attr, buf);
}
static ssize_t show_battery_chemistry(
struct device *dev, struct device_attribute *attr, char *buf)
{
/* type: string. SBS spec v1.1 p34-35: DeviceChemistry() */
return show_tp_ec_bat_str(6, 2, 5, attr, buf);
}
static ssize_t show_battery_voltage(
struct device *dev, struct device_attribute *attr, char *buf)
{
return show_tp_ec_bat_u16(1, 6, 1, NULL, attr, buf); /* type: mV */
/* units: mV. SBS spec v1.1 p24: Voltage() */
return show_tp_ec_bat_u16(1, 6, 1, NULL, attr, buf);
}
static ssize_t show_battery_design_voltage(
struct device *dev, struct device_attribute *attr, char *buf)
{
return show_tp_ec_bat_u16(3, 4, 1, NULL, attr, buf); /* type: mV */
/* units: mV. SBS spec v1.1 p32: DesignVoltage() */
return show_tp_ec_bat_u16(3, 4, 1, NULL, attr, buf);
}
static ssize_t show_battery_charging_max_voltage(
struct device *dev, struct device_attribute *attr, char *buf)
{
/* units: mV. SBS spec v1.1 p37,39: ChargingVoltage() */
return show_tp_ec_bat_u16(9, 8, 1, NULL, attr, buf);
}
static ssize_t show_battery_group0_voltage(
struct device *dev, struct device_attribute *attr, char *buf)
{
return show_tp_ec_bat_u16(0xA, 12, 1, NULL, attr, buf); /* type: mV */
/* units: mV */
return show_tp_ec_bat_u16(0xA, 12, 1, NULL, attr, buf);
}
static ssize_t show_battery_group1_voltage(
struct device *dev, struct device_attribute *attr, char *buf)
{
return show_tp_ec_bat_u16(0xA, 10, 1, NULL, attr, buf); /* type: mV */
/* units: mV */
return show_tp_ec_bat_u16(0xA, 10, 1, NULL, attr, buf);
}
static ssize_t show_battery_group2_voltage(
struct device *dev, struct device_attribute *attr, char *buf)
{
return show_tp_ec_bat_u16(0xA, 8, 1, NULL, attr, buf); /* type: mV */
/* units: mV */
return show_tp_ec_bat_u16(0xA, 8, 1, NULL, attr, buf);
}
static ssize_t show_battery_group3_voltage(
struct device *dev, struct device_attribute *attr, char *buf)
{
return show_tp_ec_bat_u16(0xA, 6, 1, NULL, attr, buf); /* type: mV */
/* units: mV */
return show_tp_ec_bat_u16(0xA, 6, 1, NULL, attr, buf);
}
static ssize_t show_battery_current_now(
struct device *dev, struct device_attribute *attr, char *buf)
{
return show_tp_ec_bat_s16(1, 8, 1, 0, attr, buf); /* type: mA */
/* units: mA. SBS spec v1.1 p24: Current() */
return show_tp_ec_bat_s16(1, 8, 1, 0, attr, buf);
}
static ssize_t show_battery_current_avg(
struct device *dev, struct device_attribute *attr, char *buf)
{
return show_tp_ec_bat_s16(1, 10, 1, 0, attr, buf); /* type: mA */
/* units: mA. SBS spec v1.1 p24: AverageCurrent() */
return show_tp_ec_bat_s16(1, 10, 1, 0, attr, buf);
}
static ssize_t show_battery_charging_max_current(
struct device *dev, struct device_attribute *attr, char *buf)
{
/* units: mA. SBS spec v1.1 p36,38: ChargingCurrent() */
return show_tp_ec_bat_s16(9, 6, 1, 0, attr, buf);
}
static ssize_t show_battery_power_now(
struct device *dev, struct device_attribute *attr, char *buf)
{
return show_tp_ec_bat_power(1, 6, 8, attr, buf); /* type: mW */
/* units: mW. SBS spec v1.1: Voltage()*Current() */
return show_tp_ec_bat_power(1, 6, 8, attr, buf);
}
static ssize_t show_battery_power_avg(
struct device *dev, struct device_attribute *attr, char *buf)
{
return show_tp_ec_bat_power(1, 6, 10, attr, buf); /* type: mW */
/* units: mW. SBS spec v1.1: Voltage()*AverageCurrent() */
return show_tp_ec_bat_power(1, 6, 10, attr, buf);
}
static ssize_t show_battery_remaining_percent(
struct device *dev, struct device_attribute *attr, char *buf)
{
return show_tp_ec_bat_u16(1, 12, 1, NULL, attr, buf); /* type: % */
/* units: percent. SBS spec v1.1 p25: RelativeStateOfCharge() */
return show_tp_ec_bat_u16(1, 12, 1, NULL, attr, buf);
}
static ssize_t show_battery_remaining_charging_time(
struct device *dev, struct device_attribute *attr, char *buf)
{
return show_tp_ec_bat_u16(2, 8, 1, "not_charging",
attr, buf); /* type: minutes */
/* units: minutes. SBS spec v1.1 p27: AverageTimeToFull() */
return show_tp_ec_bat_u16(2, 8, 1, "not_charging", attr, buf);
}
static ssize_t show_battery_remaining_running_time(
struct device *dev, struct device_attribute *attr, char *buf)
{
return show_tp_ec_bat_u16(2, 6, 1, "not_discharging",
attr, buf); /* type: minutes */
/* units: minutes. SBS spec v1.1 p27: RunTimeToEmpty() */
return show_tp_ec_bat_u16(2, 6, 1, "not_discharging", attr, buf);
}
static ssize_t show_battery_remaining_running_time_now(
struct device *dev, struct device_attribute *attr, char *buf)
{
/* units: minutes. SBS spec v1.1 p27: RunTimeToEmpty() */
return show_tp_ec_bat_u16(2, 4, 1, "not_discharging", attr, buf);
}
static ssize_t show_battery_remaining_capacity(
struct device *dev, struct device_attribute *attr, char *buf)
{
return show_tp_ec_bat_u16(1, 14, 10, "", attr, buf); /* type: mWh */
/* units: mWh. SBS spec v1.1 p26. */
return show_tp_ec_bat_u16(1, 14, 10, "", attr, buf);
}
static ssize_t show_battery_last_full_capacity(
struct device *dev, struct device_attribute *attr, char *buf)
{
return show_tp_ec_bat_u16(2, 2, 10, "", attr, buf); /* type: mWh */
/* units: mWh. SBS spec v1.1 p26: FullChargeCapacity() */
return show_tp_ec_bat_u16(2, 2, 10, "", attr, buf);
}
static ssize_t show_battery_design_capacity(
struct device *dev, struct device_attribute *attr, char *buf)
{
return show_tp_ec_bat_u16(3, 2, 10, "", attr, buf); /* type: mWh */
/* units: mWh. SBS spec v1.1 p32: DesignCapacity() */
return show_tp_ec_bat_u16(3, 2, 10, "", attr, buf);
}
static ssize_t show_battery_cycle_count(
struct device *dev, struct device_attribute *attr, char *buf)
{
return show_tp_ec_bat_u16(2, 12, 1, "", attr, buf); /* type: ordinal */
/* units: ordinal. SBS spec v1.1 p32: CycleCount() */
return show_tp_ec_bat_u16(2, 12, 1, "", attr, buf);
}
static ssize_t show_battery_temperature(
struct device *dev, struct device_attribute *attr, char *buf)
{
/* units: millicelsius. SBS spec v1.1: Temperature()*10 */
return show_tp_ec_bat_s16(1, 4, 100, -273100, attr, buf);
/* type: millicelsius */
}
static ssize_t show_battery_serial(
struct device *dev, struct device_attribute *attr, char *buf)
{
return show_tp_ec_bat_u16(3, 10, 1, "", attr, buf); /* type: int */
/* type: int. SBS spec v1.1 p34: SerialNumber() */
return show_tp_ec_bat_u16(3, 10, 1, "", attr, buf);
}
static ssize_t show_battery_manufacture_date(
struct device *dev, struct device_attribute *attr, char *buf)
{
return show_tp_ec_bat_date(3, 8, attr, buf); /* type: YYYY-MM-DD */
/* type: YYYY-MM-DD. SBS spec v1.1 p34: ManufactureDate() */
return show_tp_ec_bat_date(3, 8, attr, buf);
}
static ssize_t show_battery_first_use_date(
struct device *dev, struct device_attribute *attr, char *buf)
{
return show_tp_ec_bat_date(8, 2, attr, buf); /* type: YYYY-MM-DD */
/* type: YYYY-MM-DD */
return show_tp_ec_bat_date(8, 2, attr, buf);
}
/**
@ -1275,14 +1322,17 @@ static struct attribute_group tp_root_attribute_group = {
_ATTR_R(_BAT, group3_voltage) \
_ATTR_R(_BAT, current_now) \
_ATTR_R(_BAT, current_avg) \
_ATTR_R(_BAT, charging_max_current) \
_ATTR_R(_BAT, power_now) \
_ATTR_R(_BAT, power_avg) \
_ATTR_R(_BAT, remaining_percent) \
_ATTR_R(_BAT, remaining_charging_time) \
_ATTR_R(_BAT, remaining_running_time) \
_ATTR_R(_BAT, remaining_running_time_now) \
_ATTR_R(_BAT, remaining_capacity) \
_ATTR_R(_BAT, last_full_capacity) \
_ATTR_R(_BAT, design_voltage) \
_ATTR_R(_BAT, charging_max_voltage) \
_ATTR_R(_BAT, design_capacity) \
_ATTR_R(_BAT, cycle_count) \
_ATTR_R(_BAT, temperature) \