Android 2.3 relies on driver side input calibration and does not offer any calibration tools on its own, which can be a problem when using generic drivers or several devices with the same driver. This guide shows how to add a common 5 point touch input calibration to the Android system.

Obtaining and validating calibration values

The first step is to acquire the calibration values. tslib comes with a variety of useful tools to find and test calibration parameters.

Prepare tslib

Project Kennel has a guide on how to build tslib for Android. Due to some minor issues I experienced with the tslib version recommended by this site, I used the latest source code from the tslib GitHub repository (1.0-102-g1fd999e). Based on the instructions and patches from Project Kennel, I patched this version for the use on Android and reused the Android.mk file with some adjustments (see download section).

Note that the input device is hard coded into many of the tslib source files. With Gingerbread on the Beagleboard xM it has to be changed to /dev/input/event3.

Unfortunately the tslib utilities was not refreshing the framebuffer correctly on my hardware configuration (I used a Lilliput UM-80/C/T screen). A workaround is to close and reopen the framebuffer file descriptor manually to refresh the image. This does lead to some display errors, but all of the crosshairs on the screen are now visible.

Once all patches have been applied, tslib is ready to be built. To use the Android build system for that, we move it to the Android source tree

~/Downloads # mv tslib ~/workspace/external/tslib

with ~/workspace being the root directory of the Android source.

Building and installing tslib

We can now build tslib with following commands:

~/workspace # source build/envsetup.sh
~/workspace # make libts
~/workspace # make ts/plugins/input
~/workspace # make ts/plugins/pthres
~/workspace # make ts/plugins/dejitter
~/workspace # make ts/plugins/linear
~/workspace # make ts/plugins/variance
~/workspace # make ts_calibrate
~/workspace # make ts_test

The new binaries and libraries are then copied onto the system:

~/workspace # adb push out/target/product/generic/system/lib/libts.so /system/lib/libts.so
~/workspace # adb push out/target/product/generic/system/lib/ts/plugins/dejitter.so /system/lib/ts/plugins/dejitter.so
~/workspace # adb push out/target/product/generic/system/lib/ts/plugins/input.so /system/lib/ts/plugins/input.so
~/workspace # adb push out/target/product/generic/system/lib/ts/plugins/linear.so /system/lib/ts/plugins/linear.so
~/workspace # adb push out/target/product/generic/system/lib/ts/plugins/pthres.so /system/lib/ts/plugins/pthres.so
~/workspace # adb push out/target/product/generic/system/lib/ts/plugins/variance.so /system/lib/ts/plugins/variance.so
~/workspace # adb push out/target/product/generic/system/bin/ts_calibrate /system/ bin/ts_calibrate
~/workspace # adb push out/target/product/generic/system/bin/ts_test /system/bin/ts_test

In addition to that, we also need a configuration file that comes with the tslib source. Here we have to enable the input module first by uncommenting the line

# module_raw input

before the file can be transfered to the device.

~/workspace # adb push external/tslib/etc/ts.conf /system/etc/ts.conf

Running tslib

In order to run any tslib utility, we have to stop Android.

root@android# stop zygote

Tslib uses a few environment variables for configuration which we have to set first:

root@android# export TSLIB_TSDEVICE=/dev/input/event3
root@android# export TSLIB_CALIBFILE=/system/etc/pointercal
root@android# export TSLIB_CONFFILE=/system/etc/ts.conf
root@android# export TSLIB_PLUGINDIR=/system/lib/ts/plugins
root@android# export TSLIB_FBDEVICE=/dev/graphics/fb0
root@android# export TSLIB_CONSOLEDEVICE=/dev/tty

Then calibration values can then be determined with ts_calibrate.

root@android# ts_calibrate

Once the calibration process is finished, the values are written to the /system/etc/pointercal file. Now we can use ts_test to check if these values are correct.

root@android# ts_test

Touching the screen should now move the crosshair on the screen to this position. Otherwise the calibration is not correct and previous step needs to be repeated.

Modify the Android input processing

This post shows a possible implementation of 5 point calibration for Android’s InputReader. The calibration parameters are taken from the /system/etc/pointercal file on the device which uses following format:

xscale, xymix, xoffset, yxmix, yscale, yoffset, divider

After applying the patch and either creating the correct .idc file (or hard coding the values into the InputReader.cpp), we just need to swap up the libui.so on the device.

~/workspace # make libui
~/workspace # adb push out/target/product/generic/system/lib/ts/libui.so /system/ lib/libui.so

Now all touch input coordinates are processed using the calibration values. The Multitouch Visible Test app can be used to check this. The source code can be found here. Alternatively the app is also available on Android market. The functionality is very similar to ts_test, it shows an indicator where the touch event is located. On a calibrated screen, it should always be right below the touch point.

Downloads

tslib-Android patches: