# Specification for Generic Touch Screen Driver

Version: 0.2 (draft)

Last Updated: 17-July-2000

## 1. Major Number and Minor Numbers

A generic Touch Screen major and minor numbers to be registered according to the procedure documented in ../linux/Documentation/devices.txt. New registrations are to be sent to the address device@lanana.org.

A major number 10 seems the most likely candidate at this stage (TBD).

## 2. Resolution

In some applications high (sub-pixel) resolution may be required from the device driver for graphical tasks such as drawing (digital ink) and/or hand writing recognition (HWR). In other applications lower (pixel) resolution may be required for core pointer control of menus and other applications. In many applications, however, it is desirable to do both at once.

To achieve this goal in X, several extensions have been added to the X Input support in XFree86 they are currently under investigation for use with this driver. (See the Owen Taylor link below).

From the driver point of view the high (sub-pixel) resolution data are passed to it’s client via the user space and kernel read() functions . The client of the driver will be able to convert to pixel resolution, if required, by using the previously saved affine transform parameters x[y]scale and x[y]trans. (see the Calibration section below).

/dev/ts

This is the device name used to return “raw” sub-pixel resolution coordinates from the digitizer. (Note 3)

## 3. Touch Screen Event Structure (TS_EVENT)

typedef struct {

short pressure; /* Note 1 */

int x;

int y;

#if 1

int millisecs; /* milliseconds time stamp */

#else

struct timeval timestamp; /* microsecs resolution ? */

#endif

} TS_EVENT;

This structure is generated by the driver module and passed to the user space by the _read() file operation. It is received by the user space read()function.

Each event has it’s own time stamp which may be used to measure pen velocity and/or serialize events from different devices. It is still debatable whether we use microsecond resolution or millisecond resolution. For maximum accuracy the time stamp is created by the interrupt service routine in the kernel.

Pressure indicates a pen up or pen down event. The Cartesian coordinates (x and y) (Note 2) indicate the position of a pen down event. Cartesian coordinates have no meaning for a pen up event.

Although the event is shown in TS_EVENT consist of a simple set of cartesian coordinates and a pressure attribute, work is still under way investigating a more general case which would cater for more sophisticated digitizers such as the range of Wacom tablets. These devices have typically more than one pen type – each pen type having it’s own attributes. For example the Wacom can have three pen types (pen,puck or airbrush) with the airbrush, alone, requiring five parameters - x, y, z(distance from paper),air_volume and paint_volume. In addition to pen types there maybe pen colours, sylus angle etc to worry about.

Owen Taylor’s web site at:

http://www.gtk.org/~otaylor/index.html

describes work already been done for Watcom Artpad II devices using GMIP (Gnu Image Manipulation Program),GTK+ (Gmip Tool Kit) and the X Input extension

## 4. User Level File Operations

In addition to open(), close() and ioctl() functions, blocking and non-blocking read() and asynchronous notification (SIGIO) should be supported at the user level. The select/poll mechanism will also be supported.

## 5. Kernel Level File Operations

_read()

Blocking reads will block until a TS_EVENT structure (see below) can be returned.

_fasync()

SIGIO to user when there is an event to report. An event is defined as reception of a complete TS_EVENT structure.

_poll()

If there are 1 or more TS_EVENT structures to be read then this function will return the (POLLIN | POLLRDNORM) flags otherwise a zero will be returned.

_ioctl()

The list of ioctls will depend on the hardware used to implement the touch screen (example UCB1200). Initialisation ioctls will be called by the driver’s init_module() or equivalent.

The ioctl command numbers should be ‘mangled’ using the _IO,_IOW,_IOR,_IOWR macros as defined in <linux/ioctl.h>

A ‘magic number’ of ‘t’ should be used (see CALIBRATION section)

#define IOC_MAGIC ‘t’

See the calibration section for ioctl usage.

## 6. Touch Screen Example Code

The following example code can be found in the ../apps/h3600_test directory on the http://www.handhelds.org/ CVS tree.

ts_poll.c

example of a non-blocking read using the poll/select mechanism.

ts_read.c

example of a blocking read.

fasynctst.c

example of how asynchronous notifications are handled in user space.

The Compaq iPAQ touch screen driver (h3650_ts.c) implements the above file operations and can be found in the ../drivers/char directory in the http://www.handhelds.org/ CVS tree.

## 7. Calibration

It was has been stated that “most” devices will work with a single affine (linear) transform. This section describes the calibration technique used by Itsy and the Compaq iPAQ which uses an affine transform with zero shear and rotation. (Q: If this is an affine transform then will shear and rotation be necessary?)

For a good introduction to the affine transform see

http://gamelan.earthweb.com/javaprogramming/baldwin/new/030700_J306.html#_What_is_an

The affine matrix (calibration parameters x/yscale and x/ytrans) are calculated by a separate calibration application (note 4). It assumes zero shear and rotation.

Xcal = (xscale * Xraw) + xtrans

Ycal = (yscale * Yraw) + ytrans

Xcal and Ycal are the (pixel resolution) Cartesian coordinates.

Xraw and Yraw are the high (sub-pixel resolution) Cartesian coordinates.

Xscale and Yscale are the scaling factor

Xtrans and Ytrans are the translation.factor.

For increased accuracy xscale and yscale are multiplied by 256 and stored in the TS_CAL structure in the driver.

Xscale = xscale << 8

Yscale = yscale << 8

During conversion from Xraw to Xcal the reverse transformation is required.

Xcal = ( (Xscale * Xraw) >> 8 ) + xtrans

Ycal = ( (Yscale * Yraw) >> 8 ) + ytrans

The affine transform matrix (calibration information) is held in the TS_CAL structure. It is stored in the driver using the TS_SET_CALIBRATE ioctl.

Applications requiring sub-pixel to pixel transformations can retrieve the matrix in structure TS_CAL using the TS_GET_CALIBRATE ioctls.

#define TS_SET_CALIBRATE _IOW(IOC_MAGIC,0,TS_CAL);

#define TS_GET_CALIBRATE _IOW(IOC_MAGIC,1,TS_CAL);

The TS_CAL structure is used to convert high (sub-pixel) resolution coordinates (Xraw and Yraw) to pixel coordinates (Xcal and Ycal) suitable for core pointer control of menus and other applications.

typedef struct {

int Xscale; /* Xscale = xscale << 8 */

int xtrans;

int Yscale; /* Yscale = yscale << 8 */

int ytrans;

} TS_CAL;

## 8. Touch Screen Calibration Application Example Code

The H3600 calibration application can be found in ../apps/calibrate.c. This code is extensively commented and will explain how the Itsy calibration application works. Note is uses a device called /dev/h3600_tsraw to get raw data.

## 9. Notes

1. Some systems return pressure as a value between 0 and xxxx which is used to determine the pen status (pen up or pen down). The Compaq iPAQ H3600 just returns pressure=0 (pen up) or pressure=1 (pen down). If pen up then the X and Y coordinates meaningless and are set to –1.
2. Cartesian coordinate system is assumed for the present however a more general approach may be to probe for the coordinate system the driver will return ( Cartesian , polar or “other”).
3. Another technique is to have two devices, each with the same major number but different minor numbers. One device (/dev/tsc ) would return normalized (pixel) data and the other (/dev/ts) would return sub-pixel “raw” data. Both devices would be able to be accessed concurrently. Clients of the driver would therefore have the choice of either “cooking” the data themselves (by multiplying the raw data with the pre-stored calibration data – x/ytrans and x/yscale) or getting the kernel to return it already “cooked” via the /dev/tsc device.
4. During boot if the affine parameters (x/yscale and x/ytrans) havn’t been calculated then the system needs to automatically fire up the calibration algorithm to calculate them.