WM97xx touchscreen machine drivers
The standard WM97xx touchscreen driver supports polled touchscreen measurements using the device and AC97 link and will operate on any system using one of these controllers. It also supports integration with a machine-specific driver which can utilise additional features of the devices, including interrupt driven pen down detection for minimisation of power consumption, in conjunction with suitable external circuitry.
A sample driver implementing most of these features is provided for the Mainstone reference platform in drivers/input/touchscreen/mainstone-wm97xx.c. One for AVR32 is provided in drivers/input/touchscreen/at32-wm97xx.c.
Registering the machine driver
When it starts the core WM97xx touchscreen driver registers a platform device called wm97xx-touch. A machine-specific platform driver can register as a driver for this device which will be started when the core driver is started. When loaded this driver should use the wm97xx_register_mach_ops() function to register callbacks with the core driver providing machine specific functionality. The callbacks for each piece of functionality are discussed in the sections below.
Interrupt driven operation
The WM97xx driver can use an interrupt generated by the WM97xx to detect pen down when supported by the hardware.
Prior to calling wm97xx_register_mach_ops() the machine-specific driver should configure the host processor to accept an interrupt on the appropriate pin using the APIs provided by the platform. It should also set wm->pen_irq to the interrupt number to be used by the core driver when calling request_irq(). The machine-specific driver should also initialise these fields in the structure passed to wm97xx_register_mach_ops():
void irq_enable(struct wm97xx *wm, int enable);
Enable or disable pen down interrupts, usually using either the interrupt controller on the host or a FPGA. This function is mandatory when interrupts are used.
This should be set to the WM97XX_GPIO_ constant for the GPIO on the WM97xx which should be used to signal interrupts. For example, then PENDOWN interrupt on the WM971x is WM97XX_GPIO_3.
(To be completed, see drivers/input/touchscreen/mainstone-wm97xx.c for an example.)
int acc_pen_down(struct wm97xx *wm);
The pen down function will be called by the core while the pen is reported as down. It should read the status from the AC97 controller, report one reading to the input subsystem and return a value which is constructed by oring the following constants together:
void wm97xx_acc_pen_up(struct wm97xx *wm)
The pen up function is called by the core when the pen is raised. It should perform any cleanup required after the pen has been down, for example draining any additional samples which are queued for reading in the AC97 controller.
Synchronisation with other hardware
Some systems experience problems with interference between the analogue signals used for the touchsceen and other signals, particularly those for the display hardware. In order to help minimise these signals pre and post sample callbacks are provided to allow readings to be synchronised with other system components. These callbacks are:
int (*pre_sample)(int); int (*post_sample(int);
Typical implementations will either use a GPIO to signal another piece of hardware or block in the pre-sample callback until an operation which could cause interference to complete.
Use as a wakeup source
It is possible to use the PENDOWN signal from WM97xx touch screens as a wakeup source when the system is suspended. To do this PENDOWN must be enabled on one of the GPIOs and wm97xx_set_suspend_mode() function should be called to configure the behavior of the WM97xx touch screen while suspended:
void wm97xx_set_suspend_mode(struct wm97xx *wm, u16 mode);
mode should be set to one of these values:
#define WM97XX_PRP_DETW 0x4000 /* detect on, digitise off, wake */ #define WM97XX_PRP_DET 0x8000 /* detect on, digitise off, no wake */ #define WM97XX_PRP_DET_DIG 0xc000 /* detect on, digitise on */
Most systems should use WM97XX_PRP_DET which will cause the PENDOWN signal to be generated, allowing the CPU to initiate system wakeup. PENDOWN will only be enabled if an application has the touch screen device open when the system is suspended.
If no value for suspend_mode is set then the drivers will power down the touch screen when the system is suspended.