2008-07-07 11:56:30 -04:00
/*
* Sahara TouchIT - 213 serial touchscreen driver
*
* Copyright ( c ) 2007 - 2008 Claudio Nieder < private @ claudio . ch >
*
* Based on Touchright driver ( drivers / input / touchscreen / touchright . c )
* Copyright ( c ) 2006 Rick Koch < n1gp @ hotmail . com >
* Copyright ( c ) 2004 Vojtech Pavlik
* and Dan Streetman < ddstreet @ ieee . org >
*/
/*
* This program is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation .
*/
# include <linux/errno.h>
# include <linux/kernel.h>
# include <linux/module.h>
# include <linux/slab.h>
# include <linux/input.h>
# include <linux/serio.h>
# define DRIVER_DESC "Sahara TouchIT-213 serial touchscreen driver"
MODULE_AUTHOR ( " Claudio Nieder <private@claudio.ch> " ) ;
MODULE_DESCRIPTION ( DRIVER_DESC ) ;
MODULE_LICENSE ( " GPL " ) ;
/*
* Definitions & global arrays .
*/
/*
* Data is received through COM1 at 9600 bit / s , 8 bit , no parity in packets
* of 5 byte each .
*
* + - - - - - - - - + + - - - - - - - - + + - - - - - - - - + + - - - - - - - - + + - - - - - - - - +
* | 1000000 p | | 0 xxxxxxx | | 0 xxxxxxx | | 0 yyyyyyy | | 0 yyyyyyy |
* + - - - - - - - - + + - - - - - - - - + + - - - - - - - - + + - - - - - - - - + + - - - - - - - - +
* MSB LSB MSB LSB
*
* The value of p is 1 as long as the screen is touched and 0 when
* reporting the location where touching stopped , e . g . where the pen was
* lifted from the screen .
*
* When holding the screen in landscape mode as the BIOS text output is
* presented , x is the horizontal axis with values growing from left to
* right and y is the vertical axis with values growing from top to
* bottom .
*
* When holding the screen in portrait mode with the Sahara logo in its
* correct position , x ist the vertical axis with values growing from
* top to bottom and y is the horizontal axis with values growing from
* right to left .
*/
# define T213_FORMAT_TOUCH_BIT 0x01
# define T213_FORMAT_STATUS_BYTE 0x80
# define T213_FORMAT_STATUS_MASK ~T213_FORMAT_TOUCH_BIT
/*
* On my Sahara Touch - IT 213 I have observed x values from 0 to 0x7f0
* and y values from 0x1d to 0x7e9 , so the actual measurement is
* probably done with an 11 bit precision .
*/
# define T213_MIN_XC 0
# define T213_MAX_XC 0x07ff
# define T213_MIN_YC 0
# define T213_MAX_YC 0x07ff
/*
* Per - touchscreen data .
*/
struct touchit213 {
struct input_dev * dev ;
struct serio * serio ;
int idx ;
unsigned char csum ;
unsigned char data [ 5 ] ;
char phys [ 32 ] ;
} ;
static irqreturn_t touchit213_interrupt ( struct serio * serio ,
unsigned char data , unsigned int flags )
{
struct touchit213 * touchit213 = serio_get_drvdata ( serio ) ;
struct input_dev * dev = touchit213 - > dev ;
touchit213 - > data [ touchit213 - > idx ] = data ;
switch ( touchit213 - > idx + + ) {
case 0 :
if ( ( touchit213 - > data [ 0 ] & T213_FORMAT_STATUS_MASK ) ! =
T213_FORMAT_STATUS_BYTE ) {
pr_debug ( " unsynchronized data: 0x%02x \n " , data ) ;
touchit213 - > idx = 0 ;
}
break ;
case 4 :
touchit213 - > idx = 0 ;
input_report_abs ( dev , ABS_X ,
( touchit213 - > data [ 1 ] < < 7 ) | touchit213 - > data [ 2 ] ) ;
input_report_abs ( dev , ABS_Y ,
( touchit213 - > data [ 3 ] < < 7 ) | touchit213 - > data [ 4 ] ) ;
input_report_key ( dev , BTN_TOUCH ,
touchit213 - > data [ 0 ] & T213_FORMAT_TOUCH_BIT ) ;
input_sync ( dev ) ;
break ;
}
return IRQ_HANDLED ;
}
/*
* touchit213_disconnect ( ) is the opposite of touchit213_connect ( )
*/
static void touchit213_disconnect ( struct serio * serio )
{
struct touchit213 * touchit213 = serio_get_drvdata ( serio ) ;
input_get_device ( touchit213 - > dev ) ;
input_unregister_device ( touchit213 - > dev ) ;
serio_close ( serio ) ;
serio_set_drvdata ( serio , NULL ) ;
input_put_device ( touchit213 - > dev ) ;
kfree ( touchit213 ) ;
}
/*
* touchit213_connect ( ) is the routine that is called when someone adds a
* new serio device that supports the Touchright protocol and registers it as
* an input device .
*/
static int touchit213_connect ( struct serio * serio , struct serio_driver * drv )
{
struct touchit213 * touchit213 ;
struct input_dev * input_dev ;
int err ;
touchit213 = kzalloc ( sizeof ( struct touchit213 ) , GFP_KERNEL ) ;
input_dev = input_allocate_device ( ) ;
if ( ! touchit213 | | ! input_dev ) {
err = - ENOMEM ;
goto fail1 ;
}
touchit213 - > serio = serio ;
touchit213 - > dev = input_dev ;
snprintf ( touchit213 - > phys , sizeof ( touchit213 - > phys ) ,
" %s/input0 " , serio - > phys ) ;
input_dev - > name = " Sahara Touch-iT213 Serial TouchScreen " ;
input_dev - > phys = touchit213 - > phys ;
input_dev - > id . bustype = BUS_RS232 ;
input_dev - > id . vendor = SERIO_TOUCHIT213 ;
input_dev - > id . product = 0 ;
input_dev - > id . version = 0x0100 ;
input_dev - > dev . parent = & serio - > dev ;
input_dev - > evbit [ 0 ] = BIT_MASK ( EV_KEY ) | BIT_MASK ( EV_ABS ) ;
input_dev - > keybit [ BIT_WORD ( BTN_TOUCH ) ] = BIT_MASK ( BTN_TOUCH ) ;
input_set_abs_params ( touchit213 - > dev , ABS_X ,
T213_MIN_XC , T213_MAX_XC , 0 , 0 ) ;
input_set_abs_params ( touchit213 - > dev , ABS_Y ,
T213_MIN_YC , T213_MAX_YC , 0 , 0 ) ;
serio_set_drvdata ( serio , touchit213 ) ;
err = serio_open ( serio , drv ) ;
if ( err )
goto fail2 ;
err = input_register_device ( touchit213 - > dev ) ;
if ( err )
goto fail3 ;
return 0 ;
fail3 : serio_close ( serio ) ;
fail2 : serio_set_drvdata ( serio , NULL ) ;
fail1 : input_free_device ( input_dev ) ;
kfree ( touchit213 ) ;
return err ;
}
/*
* The serio driver structure .
*/
2017-08-18 17:11:56 -07:00
static const struct serio_device_id touchit213_serio_ids [ ] = {
2008-07-07 11:56:30 -04:00
{
. type = SERIO_RS232 ,
. proto = SERIO_TOUCHIT213 ,
. id = SERIO_ANY ,
. extra = SERIO_ANY ,
} ,
{ 0 }
} ;
MODULE_DEVICE_TABLE ( serio , touchit213_serio_ids ) ;
static struct serio_driver touchit213_drv = {
. driver = {
. name = " touchit213 " ,
} ,
. description = DRIVER_DESC ,
. id_table = touchit213_serio_ids ,
. interrupt = touchit213_interrupt ,
. connect = touchit213_connect ,
. disconnect = touchit213_disconnect ,
} ;
2012-04-03 23:50:17 -07:00
module_serio_driver ( touchit213_drv ) ;