2005-04-17 02:20:36 +04:00
/*
* Driver for DEC VSXXX - AA mouse ( hockey - puck mouse , ball or two rollers )
2005-05-29 11:28:29 +04:00
* DEC VSXXX - GA mouse ( rectangular mouse , with ball )
* DEC VSXXX - AB tablet ( digitizer with hair cross or stylus )
2005-04-17 02:20:36 +04:00
*
* Copyright ( C ) 2003 - 2004 by Jan - Benedict Glaw < jbglaw @ lug - owl . de >
*
* The packet format was initially taken from a patch to GPM which is ( C ) 2001
* by Karsten Merker < merker @ linuxtag . org >
* and Maciej W . Rozycki < macro @ ds2 . pg . gda . pl >
* Later on , I had access to the device ' s documentation ( referenced below ) .
*/
/*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
*/
/*
* Building an adaptor to DE9 / DB25 RS232
* ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
*
* DISCLAIMER : Use this description AT YOUR OWN RISK ! I ' ll not pay for
* anything if you break your mouse , your computer or whatever !
*
* In theory , this mouse is a simple RS232 device . In practice , it has got
* a quite uncommon plug and the requirement to additionally get a power
* supply at + 5 V and - 12 V .
*
* If you look at the socket / jack ( _not_ at the plug ) , we use this pin
* numbering :
* _______
* / 7 6 5 \
* | 4 - - - 3 |
* \ 2 1 /
* - - - - - - -
*
* DEC socket DE9 DB25 Note
* 1 ( GND ) 5 7 -
* 2 ( RxD ) 2 3 -
* 3 ( TxD ) 3 2 -
* 4 ( - 12 V ) - - Somewhere from the PSU . At ATX , it ' s
* the thin blue wire at pin 12 of the
* ATX power connector . Only required for
* VSXXX - AA / - GA mice .
* 5 ( + 5 V ) - - PSU ( red wires of ATX power connector
* on pin 4 , 6 , 19 or 20 ) or HDD power
* connector ( also red wire ) .
* 6 ( + 12 V ) - - HDD power connector , yellow wire . Only
* required for VSXXX - AB digitizer .
* 7 ( dev . avail . ) - - The mouse shorts this one to pin 1.
* This way , the host computer can detect
* the mouse . To use it with the adaptor ,
* simply don ' t connect this pin .
*
* So to get a working adaptor , you need to connect the mouse with three
* wires to a RS232 port and two or three additional wires for + 5 V , + 12 V and
* - 12 V to the PSU .
*
* Flow specification for the link is 4800 , 8 o1 .
*
* The mice and tablet are described in " VCB02 Video Subsystem - Technical
* Manual " , DEC EK-104AA-TM-001. You'll find it at MANX, a search engine
* specific for DEC documentation . Try
* http : //www.vt100.net/manx/details?pn=EK-104AA-TM-001;id=21;cp=1
*/
# include <linux/delay.h>
# include <linux/module.h>
# include <linux/slab.h>
# include <linux/interrupt.h>
# include <linux/input.h>
# include <linux/serio.h>
# define DRIVER_DESC "Driver for DEC VSXXX-AA and -GA mice and VSXXX-AB tablet"
2009-10-14 10:37:30 +04:00
MODULE_AUTHOR ( " Jan-Benedict Glaw <jbglaw@lug-owl.de> " ) ;
MODULE_DESCRIPTION ( DRIVER_DESC ) ;
MODULE_LICENSE ( " GPL " ) ;
2005-04-17 02:20:36 +04:00
# undef VSXXXAA_DEBUG
# ifdef VSXXXAA_DEBUG
2009-10-14 10:37:30 +04:00
# define DBG(x...) printk(x)
2005-04-17 02:20:36 +04:00
# else
# define DBG(x...) do {} while (0)
# endif
# define VSXXXAA_INTRO_MASK 0x80
# define VSXXXAA_INTRO_HEAD 0x80
2009-10-14 10:37:30 +04:00
# define IS_HDR_BYTE(x) \
( ( ( x ) & VSXXXAA_INTRO_MASK ) = = VSXXXAA_INTRO_HEAD )
2005-04-17 02:20:36 +04:00
# define VSXXXAA_PACKET_MASK 0xe0
# define VSXXXAA_PACKET_REL 0x80
# define VSXXXAA_PACKET_ABS 0xc0
# define VSXXXAA_PACKET_POR 0xa0
2009-10-14 10:37:30 +04:00
# define MATCH_PACKET_TYPE(data, type) \
( ( ( data ) & VSXXXAA_PACKET_MASK ) = = ( type ) )
2005-04-17 02:20:36 +04:00
struct vsxxxaa {
2005-09-15 11:01:44 +04:00
struct input_dev * dev ;
2005-04-17 02:20:36 +04:00
struct serio * serio ;
# define BUFLEN 15 /* At least 5 is needed for a full tablet packet */
unsigned char buf [ BUFLEN ] ;
unsigned char count ;
unsigned char version ;
unsigned char country ;
unsigned char type ;
char name [ 64 ] ;
char phys [ 32 ] ;
} ;
2009-10-14 10:37:30 +04:00
static void vsxxxaa_drop_bytes ( struct vsxxxaa * mouse , int num )
2005-04-17 02:20:36 +04:00
{
2009-10-14 10:37:30 +04:00
if ( num > = mouse - > count ) {
2005-04-17 02:20:36 +04:00
mouse - > count = 0 ;
2009-10-14 10:37:30 +04:00
} else {
2014-10-25 02:33:53 +04:00
memmove ( mouse - > buf , mouse - > buf + num , BUFLEN - num ) ;
2005-04-17 02:20:36 +04:00
mouse - > count - = num ;
}
}
2009-10-14 10:37:30 +04:00
static void vsxxxaa_queue_byte ( struct vsxxxaa * mouse , unsigned char byte )
2005-04-17 02:20:36 +04:00
{
if ( mouse - > count = = BUFLEN ) {
2009-10-14 10:37:30 +04:00
printk ( KERN_ERR " %s on %s: Dropping a byte of full buffer. \n " ,
mouse - > name , mouse - > phys ) ;
vsxxxaa_drop_bytes ( mouse , 1 ) ;
2005-04-17 02:20:36 +04:00
}
2009-10-14 10:37:30 +04:00
DBG ( KERN_INFO " Queueing byte 0x%02x \n " , byte ) ;
2005-04-17 02:20:36 +04:00
mouse - > buf [ mouse - > count + + ] = byte ;
}
2009-10-14 10:37:30 +04:00
static void vsxxxaa_detection_done ( struct vsxxxaa * mouse )
2005-04-17 02:20:36 +04:00
{
switch ( mouse - > type ) {
2009-10-14 10:37:30 +04:00
case 0x02 :
strlcpy ( mouse - > name , " DEC VSXXX-AA/-GA mouse " ,
sizeof ( mouse - > name ) ) ;
break ;
case 0x04 :
strlcpy ( mouse - > name , " DEC VSXXX-AB digitizer " ,
sizeof ( mouse - > name ) ) ;
break ;
default :
snprintf ( mouse - > name , sizeof ( mouse - > name ) ,
" unknown DEC pointer device (type = 0x%02x) " ,
mouse - > type ) ;
break ;
2005-04-17 02:20:36 +04:00
}
2009-10-14 10:37:30 +04:00
printk ( KERN_INFO
2006-06-26 09:45:10 +04:00
" Found %s version 0x%02x from country 0x%02x on port %s \n " ,
mouse - > name , mouse - > version , mouse - > country , mouse - > phys ) ;
2005-04-17 02:20:36 +04:00
}
/*
* Returns number of bytes to be dropped , 0 if packet is okay .
*/
2009-10-14 10:37:30 +04:00
static int vsxxxaa_check_packet ( struct vsxxxaa * mouse , int packet_len )
2005-04-17 02:20:36 +04:00
{
int i ;
/* First byte must be a header byte */
2009-10-14 10:37:30 +04:00
if ( ! IS_HDR_BYTE ( mouse - > buf [ 0 ] ) ) {
DBG ( " vsck: len=%d, 1st=0x%02x \n " , packet_len , mouse - > buf [ 0 ] ) ;
2005-04-17 02:20:36 +04:00
return 1 ;
}
/* Check all following bytes */
2009-10-14 10:37:30 +04:00
for ( i = 1 ; i < packet_len ; i + + ) {
if ( IS_HDR_BYTE ( mouse - > buf [ i ] ) ) {
printk ( KERN_ERR
" Need to drop %d bytes of a broken packet. \n " ,
i - 1 ) ;
DBG ( KERN_INFO " check: len=%d, b[%d]=0x%02x \n " ,
packet_len , i , mouse - > buf [ i ] ) ;
return i - 1 ;
2005-04-17 02:20:36 +04:00
}
}
return 0 ;
}
2009-10-14 10:37:30 +04:00
static inline int vsxxxaa_smells_like_packet ( struct vsxxxaa * mouse ,
unsigned char type , size_t len )
2005-04-17 02:20:36 +04:00
{
2009-10-14 10:37:30 +04:00
return mouse - > count > = len & & MATCH_PACKET_TYPE ( mouse - > buf [ 0 ] , type ) ;
2005-04-17 02:20:36 +04:00
}
2009-10-14 10:37:30 +04:00
static void vsxxxaa_handle_REL_packet ( struct vsxxxaa * mouse )
2005-04-17 02:20:36 +04:00
{
2005-09-15 11:01:44 +04:00
struct input_dev * dev = mouse - > dev ;
2005-04-17 02:20:36 +04:00
unsigned char * buf = mouse - > buf ;
int left , middle , right ;
int dx , dy ;
/*
* Check for normal stream packets . This is three bytes ,
* with the first byte ' s 3 MSB set to 100.
*
* [ 0 ] : 1 0 0 SignX SignY Left Middle Right
* [ 1 ] : 0 dx dx dx dx dx dx dx
* [ 2 ] : 0 dy dy dy dy dy dy dy
*/
/*
* Low 7 bit of byte 1 are abs ( dx ) , bit 7 is
* 0 , bit 4 of byte 0 is direction .
*/
dx = buf [ 1 ] & 0x7f ;
2009-10-14 10:37:30 +04:00
dx * = ( ( buf [ 0 ] > > 4 ) & 0x01 ) ? 1 : - 1 ;
2005-04-17 02:20:36 +04:00
/*
* Low 7 bit of byte 2 are abs ( dy ) , bit 7 is
* 0 , bit 3 of byte 0 is direction .
*/
dy = buf [ 2 ] & 0x7f ;
2009-10-14 10:37:30 +04:00
dy * = ( ( buf [ 0 ] > > 3 ) & 0x01 ) ? - 1 : 1 ;
2005-04-17 02:20:36 +04:00
/*
* Get button state . It ' s the low three bits
* ( for three buttons ) of byte 0.
*/
2009-10-14 10:37:30 +04:00
left = buf [ 0 ] & 0x04 ;
middle = buf [ 0 ] & 0x02 ;
right = buf [ 0 ] & 0x01 ;
2005-04-17 02:20:36 +04:00
2009-10-14 10:37:30 +04:00
vsxxxaa_drop_bytes ( mouse , 3 ) ;
2005-04-17 02:20:36 +04:00
2009-10-14 10:37:30 +04:00
DBG ( KERN_INFO " %s on %s: dx=%d, dy=%d, buttons=%s%s%s \n " ,
mouse - > name , mouse - > phys , dx , dy ,
left ? " L " : " l " , middle ? " M " : " m " , right ? " R " : " r " ) ;
2005-04-17 02:20:36 +04:00
/*
* Report what we ' ve found so far . . .
*/
2009-10-14 10:37:30 +04:00
input_report_key ( dev , BTN_LEFT , left ) ;
input_report_key ( dev , BTN_MIDDLE , middle ) ;
input_report_key ( dev , BTN_RIGHT , right ) ;
input_report_key ( dev , BTN_TOUCH , 0 ) ;
input_report_rel ( dev , REL_X , dx ) ;
input_report_rel ( dev , REL_Y , dy ) ;
input_sync ( dev ) ;
2005-04-17 02:20:36 +04:00
}
2009-10-14 10:37:30 +04:00
static void vsxxxaa_handle_ABS_packet ( struct vsxxxaa * mouse )
2005-04-17 02:20:36 +04:00
{
2005-09-15 11:01:44 +04:00
struct input_dev * dev = mouse - > dev ;
2005-04-17 02:20:36 +04:00
unsigned char * buf = mouse - > buf ;
int left , middle , right , touch ;
int x , y ;
/*
* Tablet position / button packet
*
* [ 0 ] : 1 1 0 B4 B3 B2 B1 Pr
* [ 1 ] : 0 0 X5 X4 X3 X2 X1 X0
* [ 2 ] : 0 0 X11 X10 X9 X8 X7 X6
* [ 3 ] : 0 0 Y5 Y4 Y3 Y2 Y1 Y0
* [ 4 ] : 0 0 Y11 Y10 Y9 Y8 Y7 Y6
*/
/*
* Get X / Y position . Y axis needs to be inverted since VSXXX - AB
* counts down - > top while monitor counts top - > bottom .
*/
x = ( ( buf [ 2 ] & 0x3f ) < < 6 ) | ( buf [ 1 ] & 0x3f ) ;
y = ( ( buf [ 4 ] & 0x3f ) < < 6 ) | ( buf [ 3 ] & 0x3f ) ;
y = 1023 - y ;
/*
* Get button state . It ' s bits < 4. .1 > of byte 0.
*/
2009-10-14 10:37:30 +04:00
left = buf [ 0 ] & 0x02 ;
middle = buf [ 0 ] & 0x04 ;
right = buf [ 0 ] & 0x08 ;
touch = buf [ 0 ] & 0x10 ;
2005-04-17 02:20:36 +04:00
2009-10-14 10:37:30 +04:00
vsxxxaa_drop_bytes ( mouse , 5 ) ;
2005-04-17 02:20:36 +04:00
2009-10-14 10:37:30 +04:00
DBG ( KERN_INFO " %s on %s: x=%d, y=%d, buttons=%s%s%s%s \n " ,
mouse - > name , mouse - > phys , x , y ,
left ? " L " : " l " , middle ? " M " : " m " ,
right ? " R " : " r " , touch ? " T " : " t " ) ;
2005-04-17 02:20:36 +04:00
/*
* Report what we ' ve found so far . . .
*/
2009-10-14 10:37:30 +04:00
input_report_key ( dev , BTN_LEFT , left ) ;
input_report_key ( dev , BTN_MIDDLE , middle ) ;
input_report_key ( dev , BTN_RIGHT , right ) ;
input_report_key ( dev , BTN_TOUCH , touch ) ;
input_report_abs ( dev , ABS_X , x ) ;
input_report_abs ( dev , ABS_Y , y ) ;
input_sync ( dev ) ;
2005-04-17 02:20:36 +04:00
}
2009-10-14 10:37:30 +04:00
static void vsxxxaa_handle_POR_packet ( struct vsxxxaa * mouse )
2005-04-17 02:20:36 +04:00
{
2005-09-15 11:01:44 +04:00
struct input_dev * dev = mouse - > dev ;
2005-04-17 02:20:36 +04:00
unsigned char * buf = mouse - > buf ;
int left , middle , right ;
unsigned char error ;
/*
* Check for Power - On - Reset packets . These are sent out
2007-10-20 01:22:55 +04:00
* after plugging the mouse in , or when explicitly
2005-04-17 02:20:36 +04:00
* requested by sending ' T ' .
*
* [ 0 ] : 1 0 1 0 R3 R2 R1 R0
* [ 1 ] : 0 M2 M1 M0 D3 D2 D1 D0
* [ 2 ] : 0 E6 E5 E4 E3 E2 E1 E0
* [ 3 ] : 0 0 0 0 0 Left Middle Right
*
* M : manufacturer location code
* R : revision code
* E : Error code . If it ' s in the range of 0x00 . .0 x1f , only some
2011-03-31 05:57:33 +04:00
* minor problem occurred . Errors > = 0x20 are considered bad
2005-04-17 02:20:36 +04:00
* and the device may not work properly . . .
* D : < 0010 > = = mouse , < 0100 > = = tablet
*/
mouse - > version = buf [ 0 ] & 0x0f ;
mouse - > country = ( buf [ 1 ] > > 4 ) & 0x07 ;
mouse - > type = buf [ 1 ] & 0x0f ;
error = buf [ 2 ] & 0x7f ;
/*
* Get button state . It ' s the low three bits
* ( for three buttons ) of byte 0. Maybe even the bit < 3 >
* has some meaning if a tablet is attached .
*/
2009-10-14 10:37:30 +04:00
left = buf [ 0 ] & 0x04 ;
middle = buf [ 0 ] & 0x02 ;
right = buf [ 0 ] & 0x01 ;
2005-04-17 02:20:36 +04:00
2009-10-14 10:37:30 +04:00
vsxxxaa_drop_bytes ( mouse , 4 ) ;
vsxxxaa_detection_done ( mouse ) ;
2005-04-17 02:20:36 +04:00
if ( error < = 0x1f ) {
/* No (serious) error. Report buttons */
2009-10-14 10:37:30 +04:00
input_report_key ( dev , BTN_LEFT , left ) ;
input_report_key ( dev , BTN_MIDDLE , middle ) ;
input_report_key ( dev , BTN_RIGHT , right ) ;
input_report_key ( dev , BTN_TOUCH , 0 ) ;
input_sync ( dev ) ;
2005-04-17 02:20:36 +04:00
if ( error ! = 0 )
2009-10-14 10:37:30 +04:00
printk ( KERN_INFO " Your %s on %s reports error=0x%02x \n " ,
mouse - > name , mouse - > phys , error ) ;
2005-04-17 02:20:36 +04:00
}
/*
* If the mouse was hot - plugged , we need to force differential mode
* now . . . However , give it a second to recover from it ' s reset .
*/
2009-10-14 10:37:30 +04:00
printk ( KERN_NOTICE
" %s on %s: Forcing standard packet format, "
" incremental streaming mode and 72 samples/sec \n " ,
mouse - > name , mouse - > phys ) ;
serio_write ( mouse - > serio , ' S ' ) ; /* Standard format */
mdelay ( 50 ) ;
serio_write ( mouse - > serio , ' R ' ) ; /* Incremental */
mdelay ( 50 ) ;
serio_write ( mouse - > serio , ' L ' ) ; /* 72 samples/sec */
2005-04-17 02:20:36 +04:00
}
2009-10-14 10:37:30 +04:00
static void vsxxxaa_parse_buffer ( struct vsxxxaa * mouse )
2005-04-17 02:20:36 +04:00
{
unsigned char * buf = mouse - > buf ;
int stray_bytes ;
/*
* Parse buffer to death . . .
*/
do {
/*
* Out of sync ? Throw away what we don ' t understand . Each
* packet starts with a byte whose bit 7 is set . Unhandled
* packets ( ie . which we don ' t know about or simply b0rk3d
* data . . . ) will get shifted out of the buffer after some
* activity on the mouse .
*/
while ( mouse - > count > 0 & & ! IS_HDR_BYTE ( buf [ 0 ] ) ) {
2009-10-14 10:37:30 +04:00
printk ( KERN_ERR " %s on %s: Dropping a byte to regain "
" sync with mouse data stream... \n " ,
mouse - > name , mouse - > phys ) ;
vsxxxaa_drop_bytes ( mouse , 1 ) ;
2005-04-17 02:20:36 +04:00
}
/*
* Check for packets we know about .
*/
2009-10-14 10:37:30 +04:00
if ( vsxxxaa_smells_like_packet ( mouse , VSXXXAA_PACKET_REL , 3 ) ) {
2005-04-17 02:20:36 +04:00
/* Check for broken packet */
2009-10-14 10:37:30 +04:00
stray_bytes = vsxxxaa_check_packet ( mouse , 3 ) ;
if ( ! stray_bytes )
vsxxxaa_handle_REL_packet ( mouse ) ;
2005-04-17 02:20:36 +04:00
2009-10-14 10:37:30 +04:00
} else if ( vsxxxaa_smells_like_packet ( mouse ,
VSXXXAA_PACKET_ABS , 5 ) ) {
2005-04-17 02:20:36 +04:00
/* Check for broken packet */
2009-10-14 10:37:30 +04:00
stray_bytes = vsxxxaa_check_packet ( mouse , 5 ) ;
if ( ! stray_bytes )
vsxxxaa_handle_ABS_packet ( mouse ) ;
2005-04-17 02:20:36 +04:00
2009-10-14 10:37:30 +04:00
} else if ( vsxxxaa_smells_like_packet ( mouse ,
VSXXXAA_PACKET_POR , 4 ) ) {
2005-04-17 02:20:36 +04:00
/* Check for broken packet */
2009-10-14 10:37:30 +04:00
stray_bytes = vsxxxaa_check_packet ( mouse , 4 ) ;
if ( ! stray_bytes )
vsxxxaa_handle_POR_packet ( mouse ) ;
} else {
break ; /* No REL, ABS or POR packet found */
}
if ( stray_bytes > 0 ) {
printk ( KERN_ERR " Dropping %d bytes now... \n " ,
stray_bytes ) ;
vsxxxaa_drop_bytes ( mouse , stray_bytes ) ;
2005-04-17 02:20:36 +04:00
}
} while ( 1 ) ;
}
2009-10-14 10:37:30 +04:00
static irqreturn_t vsxxxaa_interrupt ( struct serio * serio ,
unsigned char data , unsigned int flags )
2005-04-17 02:20:36 +04:00
{
2009-10-14 10:37:30 +04:00
struct vsxxxaa * mouse = serio_get_drvdata ( serio ) ;
2005-04-17 02:20:36 +04:00
2009-10-14 10:37:30 +04:00
vsxxxaa_queue_byte ( mouse , data ) ;
vsxxxaa_parse_buffer ( mouse ) ;
2005-04-17 02:20:36 +04:00
return IRQ_HANDLED ;
}
2009-10-14 10:37:30 +04:00
static void vsxxxaa_disconnect ( struct serio * serio )
2005-04-17 02:20:36 +04:00
{
2009-10-14 10:37:30 +04:00
struct vsxxxaa * mouse = serio_get_drvdata ( serio ) ;
2005-04-17 02:20:36 +04:00
2009-10-14 10:37:30 +04:00
serio_close ( serio ) ;
serio_set_drvdata ( serio , NULL ) ;
input_unregister_device ( mouse - > dev ) ;
kfree ( mouse ) ;
2005-04-17 02:20:36 +04:00
}
2009-10-14 10:37:30 +04:00
static int vsxxxaa_connect ( struct serio * serio , struct serio_driver * drv )
2005-04-17 02:20:36 +04:00
{
struct vsxxxaa * mouse ;
2005-09-15 11:01:44 +04:00
struct input_dev * input_dev ;
int err = - ENOMEM ;
2005-04-17 02:20:36 +04:00
2009-10-14 10:37:30 +04:00
mouse = kzalloc ( sizeof ( struct vsxxxaa ) , GFP_KERNEL ) ;
input_dev = input_allocate_device ( ) ;
2005-09-15 11:01:44 +04:00
if ( ! mouse | | ! input_dev )
2006-11-06 06:40:19 +03:00
goto fail1 ;
2005-04-17 02:20:36 +04:00
2005-09-15 11:01:44 +04:00
mouse - > dev = input_dev ;
mouse - > serio = serio ;
2009-10-14 10:37:30 +04:00
strlcat ( mouse - > name , " DEC VSXXX-AA/-GA mouse or VSXXX-AB digitizer " ,
sizeof ( mouse - > name ) ) ;
snprintf ( mouse - > phys , sizeof ( mouse - > phys ) , " %s/input0 " , serio - > phys ) ;
2005-09-15 11:01:44 +04:00
input_dev - > name = mouse - > name ;
input_dev - > phys = mouse - > phys ;
input_dev - > id . bustype = BUS_RS232 ;
2007-04-12 09:35:09 +04:00
input_dev - > dev . parent = & serio - > dev ;
2005-09-15 11:01:44 +04:00
2009-10-14 10:37:30 +04:00
__set_bit ( EV_KEY , input_dev - > evbit ) ; /* We have buttons */
__set_bit ( EV_REL , input_dev - > evbit ) ;
__set_bit ( EV_ABS , input_dev - > evbit ) ;
__set_bit ( BTN_LEFT , input_dev - > keybit ) ; /* We have 3 buttons */
__set_bit ( BTN_MIDDLE , input_dev - > keybit ) ;
__set_bit ( BTN_RIGHT , input_dev - > keybit ) ;
__set_bit ( BTN_TOUCH , input_dev - > keybit ) ; /* ...and Tablet */
__set_bit ( REL_X , input_dev - > relbit ) ;
__set_bit ( REL_Y , input_dev - > relbit ) ;
input_set_abs_params ( input_dev , ABS_X , 0 , 1023 , 0 , 0 ) ;
input_set_abs_params ( input_dev , ABS_Y , 0 , 1023 , 0 , 0 ) ;
serio_set_drvdata ( serio , mouse ) ;
err = serio_open ( serio , drv ) ;
2005-09-15 11:01:44 +04:00
if ( err )
2006-11-06 06:40:19 +03:00
goto fail2 ;
2005-04-17 02:20:36 +04:00
/*
* Request selftest . Standard packet format and differential
* mode will be requested after the device ID ' ed successfully .
*/
2009-10-14 10:37:30 +04:00
serio_write ( serio , ' T ' ) ; /* Test */
2005-04-17 02:20:36 +04:00
2009-10-14 10:37:30 +04:00
err = input_register_device ( input_dev ) ;
2006-11-06 06:40:19 +03:00
if ( err )
goto fail3 ;
2005-04-17 02:20:36 +04:00
return 0 ;
2005-09-15 11:01:44 +04:00
2009-10-14 10:37:30 +04:00
fail3 : serio_close ( serio ) ;
fail2 : serio_set_drvdata ( serio , NULL ) ;
fail1 : input_free_device ( input_dev ) ;
kfree ( mouse ) ;
2005-09-15 11:01:44 +04:00
return err ;
2005-04-17 02:20:36 +04:00
}
static struct serio_device_id vsxxaa_serio_ids [ ] = {
{
. type = SERIO_RS232 ,
. proto = SERIO_VSXXXAA ,
. id = SERIO_ANY ,
. extra = SERIO_ANY ,
} ,
{ 0 }
} ;
MODULE_DEVICE_TABLE ( serio , vsxxaa_serio_ids ) ;
static struct serio_driver vsxxxaa_drv = {
. driver = {
. name = " vsxxxaa " ,
} ,
. description = DRIVER_DESC ,
. id_table = vsxxaa_serio_ids ,
. connect = vsxxxaa_connect ,
. interrupt = vsxxxaa_interrupt ,
. disconnect = vsxxxaa_disconnect ,
} ;
2012-04-04 10:50:17 +04:00
module_serio_driver ( vsxxxaa_drv ) ;