Share

tpctl

File Release Notes and Changelog

Release Name: 0.16

Notes:
IBM ThinkPad SMAPI Driver v0.16
Author:  Shem Multinymous <multinymous@gmail.com>
Project: http://sourceforge.net/projects/tpctl
Wiki:    http://thinkwiki.org/wiki/tp_smapi
List:    linux-thinkpad@linux-thinkpad.org
         (http://mailman.linux-thinkpad.org/mailman/listinfo/linux-thinkpad)

Description
-----------

ThinkPad laptops include a proprietary interface called SMAPI BIOS 
(System Management Application Program Interface) which provides some
hardware control functionality that is not accessible by other means.

This driver exposes some features of the SMAPI BIOS through a sysfs 
interface. It is suitable for newer models, on which SMAPI is invoked 
through IO port writes. Older models use a different SMAPI interface; 
for those, try the "thinkpad" module from the "tpctl" package.

WARNING: 
This driver uses undocumented features and direct hardware access.
It thus cannot be guaranteed to work, and may cause arbitrary damage
(especially on models it wasn't tested on).


Installation
------------

For testing, you can simply compile and load the driver within the current
working directory:
# make load

To compile and install into the kernel's module path:
# make install

If you use the HDAPS driver, use these instead to replace the hdaps module
with one patched for compatibility with tp_smapi (kernel source tree needed):
# make load HDAPS=1
or
# make install HDAPS=1

To prepare a stand-alone patch against the current kernel tree (including
a compatibility fixes to hdaps and Kconfig entries):
# make patch

To delete all autogenerated files:
# make clean


The original kernel tree is never modified by any these commands. 
The /lib/modules directory is modified only by "make install".


Usage
-----

Control of battery charging thresholds (in percents of current full charge
capacity):

# echo 40 > /sys/devices/platform/smapi/BAT0/start_charge_thresh
# echo 70 > /sys/devices/platform/smapi/BAT0/stop_charge_thresh
# cat /sys/devices/platform/smapi/BAT0/*_charge_thresh

    (This is useful since Li-Ion batteries wear out much faster at very 
     high or low charge levels. The driver will also keeps the thresholds 
     across suspend-to-disk with AC disconnected; this isn't done 
     automatically by the hardware.)

Inhibiting battery charging for 17 minutes (overrides thresholds):

# echo 17 > /sys/devices/platform/smapi/BAT0/inhibit_charge_minutes
# echo 0  > /sys/devices/platform/smapi/BAT0/inhibit_charge_minutes  # stop
# cat /sys/devices/platform/smapi/BAT0/inhibit_charge_minutes

    (This can be used to control which battery is charged when using an 
     Ultrabay battery.)

Forcing battery discharging even if AC power available:

# echo 1 > /sys/devices/platform/smapi/BAT0/force_discharge
# echo 0 > /sys/devices/platform/smapi/BAT0/force_discharge  # stop discharge
# cat /sys/devices/platform/smapi/BAT0/force_discharge

    (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):

# 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_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/manufacturer
# cat /sys/devices/platform/smapi/BAT0/model
# cat /sys/devices/platform/smapi/BAT0/serial
# cat /sys/devices/platform/smapi/BAT0/barcoding
# cat /sys/devices/platform/smapi/BAT0/chemistry
# cat /sys/devices/platform/smapi/ac_connected

The raw status data, including some fields not in the above (in case
you can figure them out):

# cat /sys/devices/platform/smapi/BAT0/dump  

In all of the above, replace BAT0 with BAT1 to address the 2nd battery.


Setting and getting CD-ROM speed:
# echo 0 > /sys/devices/platform/smapi/cd_speed # slow
# echo 1 > /sys/devices/platform/smapi/cd_speed # medium
# echo 2 > /sys/devices/platform/smapi/cd_speed # fast
# cat /sys/devices/platform/smapi/cd_speed

NOTE: cd_speed is disabled by default ("#define PROVIDE_CD_SPEED" to enable),
since changing the CD speed when the CD kernel is also accessing the CD
(e.g., reading a file) will hang your computer. You can get the same
functionality in a safer using combination of "hdparm -E" or "eject -x" for
CD and speedcontrol (http://safari.iki.fi/speedcontrol.c) for DVD.


Model-specific status
---------------------

Works (at least partially) on the following ThinkPad model:
* G41
* R40, R50p, R51, R52
* T23, T40, T40p, T41, T41p, T42, T42p, T43, T43p
* X24, X31, X32, X40, X41

Not all functions are available on all models; for detailed status, see:
  http://thinkwiki.org/wiki/tp_smapi

Please report success/failure by e-mail or on the Wiki. 
If you get a "not implemented" or "not supported" message, your laptop 
probably just can't do that (at least not via the SMAPI BIOS).
For negative reports, follow the bug reporting guidelines below.
If you send me the necessary technical data (i.e., SMAPI function 
interfaces), I will support additional models.


Conflict with HDAPS
-------------------

The extended battery status function conflicts with the "hdaps" kernel module
(they use the same IO ports). 

You can use HDAPS=1 (see Installation) to get a patched version of hdaps which
is compatible with tp_smapi.

Otherwise:

If you load "hdaps" first, tp_smapi will disable these functions (and log a
message in the kernel log). If you load "tp_smapi" first, "hdaps" will refuse
to load. To switch between the two, "rmmod" both and then load one you need.

Some of the battery status is also visible through ACPI (/proc/acpi/battery/).

The charging control files (*_charge_thresh, inhibit_charge_minutes and
force_discrage*) don't have this problem.


Bug reporting
-------------

Mail <multinymous@gmail.com>. Please include:
* Details about your model,
* Output of "dmesg | grep smapi" after each command. Make sure the module is
  loaded with the "debug=1" parameter ("make load" does this by default).
* Output of "dmidecode | grep -C5 Product"
* Does the failed functionality works under Windows?


Files in this package
---------------------

README        This file
CHANGES       Change log
Makefile      Makefile (see "Installation" above)
tp_smapi.c    tp_smapi driver (main code)
tp_base.*     tp_base driver (coordinates hardware access between tp_smapi 
              and hdaps)
diff/hdaps-*  Patches to make the hdaps driver use tp_base.
diff/*        (other files) used by "make patch"
include       Contains a symlink to make gcc happy.


Ideas for improvement
---------------------
(The best way to get these done is to send a patch.)

Allow concurrent APS access with "hdaps" module.

Remember CD speed over suspend-to-disk (the hardware doesn't), as done
for charge thresholds.

Don't create /sys files for unsupported functions, and don't access those
functions on suspend+resume (requires probing on module load or a huge 
white/blacklist).

Support both batteries, putting the files of each battery in a separate
directory (analogously to /proc/acpi/battery/BAT0).

Make inhibit_charge_minutes return the time left, not the time originally
set (as returned by the SMAPI BIOS). Requires remembering when 
inhibit_charge_minutes was set and comparing to current time.

Save and and restore inhibit_charge_minutes across suspend-to-disk, as done
for charge thresholds (requires the above time calculations too).

Other things that can be controlled through SMAPI, but are not supported
in this version of the driver, include forcing battery discharge, disallowing 
battery charging, PCI bus power saving, CPU power saving control, extended
smart battery information and fan control. For below. I don't plain to
implement all those features, but the current framework should be a base for
contributions.


More about SMAPI
----------------

For hints about what may be possible via the SMAPI BIOS and how, see:

* IBM Technical Reference Manual for the ThinkPad 770
  (http://www-307.ibm.com/pc/support/site.wss/document.do?lndocid=PFAN-3TUQQD)
* Exported symbols in PWRMGRIF.DLL or TPPWRW32.DLL (e.g., use "objdump -x").
* drivers/char/mwave/smapi.c in the Linux kernel tree.*
* The "thinkpad" SMAPI module (http://tpctl.sourceforge.net).
* The SMAPI_* constants in tp_smapi.c (some of these are presently unused).

Note that in the above Technical Reference and in the "thinkpad" module,
SMAPI is invoked through a function call to some physical address. However,
the interface used by tp_smapi and the above mwave drive, and apparently 
required by newer ThinkPad, is different: you set the parameters up in the 
CPU's registers and write to ports 0xB2 (the APM control port) and 0x4F; this
triggers an SMI (System Management Interrupt), causing the CPU to enter
SMM (System Management Mode) and run the BIOS firmware; the results are 
returned in the CPU's registers. It is not clear what is the relation between 
the two variants of SMAPI, though the assignment of error codes seems to be 
similar.

In addition to the above, battery information is accessible through IO ports
0x1604-0x161F (these provide a virtual address space, which exposes both 
battery information and HDAPS accelerometer data). It's not clear which
hardware component handles these ports; maybe it's another interface to the
embedded controller (in addition to the above SMAPI protocol and the standard
EC interface at ports 0x62,0x66).


Changes: Recent change history for tp_smapi: 0.16 2006-01-11 ---------------- - Renamed smapi/BAT?/force_discharge1 to smapi/BAT?/force_discharge - Removed smapi/BAT?/force_discharge2 (doesn't work on any model) - HDAPS patch changes: - Check ready status (instead of occasionally returning junk) also for variance, not just for position. - Calibrate unsynchronously (reduces load and resume time by 1-2 seconds) - Fix position readouts - read word, not byte. - Fixed driver lockup when writing to hdaps/variance. - Changes in diff handling. 0.15 2006-01-10 ---------------- - Bugfix: 0.14 had broken SM BIOS call code. 0.14 2006-01-09 ---------------- This version has no user-visible functionality changes, but improves the reliability of coordinating hardware access with the hdaps driver. - Moved controller access code to tp_base. - Changes in HDAPS driver patch: - Use tp_base for controller access instead of direct port IO. Using the "row read" and "prefetch" abstraction of tp_base makes the hdaps code shorter, clearer and safer. - Added checking of the STATUS port and automatic retries if device is not ready (previously it just returned junk values). - Added missing lock in hdaps_invert_store. - A few local code simplifications - Redue the retry delay (200ms was excessive). - Changed SMAPI calls to use 32-bit args. - Made "make patch" produce an LKML-compliant patches (include a diffstat, remove CD_SPEED, remove <2.6.15 #ifdefs). - Changes in Makefile and directory structure. 0.13 2005-12-21 ---------------- - First step toward resolving conflict with the hdaps module: - Added a tp_base module, which handles coordination of access to the ThinkPad controller (thanks to Alan Cox and Rovert Love). - Changed tp_smapi to require and use tp_base. - "make load HDAPS=1" and "make install HDAPS=1" will copy and patch hdaps.c for compatibility with tp_smapi and tp_base, and then load or install it. - Added a "make patch" target, which creates a stand-alone patch against the current kernel tree (thanks, Spiney!). - Future kernel compatibility: avoids platform_device_register_simple.