2005-04-16 15:20:36 -07:00
/*
* Amiga mouse driver for Linux / m68k
*
* Copyright ( c ) 2000 - 2002 Vojtech Pavlik
*
* Based on the work of :
* Michael Rausch James Banks
* Matther Dillon David Giller
* Nathan Laredo Linus Torvalds
* Johan Myreen Jes Sorensen
* Russell King
*/
/*
* 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/module.h>
# include <linux/init.h>
# include <linux/input.h>
# include <linux/interrupt.h>
2009-04-05 13:11:28 +02:00
# include <linux/platform_device.h>
2005-04-16 15:20:36 -07:00
# include <asm/irq.h>
# include <asm/setup.h>
# include <asm/system.h>
# include <asm/uaccess.h>
# include <asm/amigahw.h>
# include <asm/amigaints.h>
MODULE_AUTHOR ( " Vojtech Pavlik <vojtech@ucw.cz> " ) ;
MODULE_DESCRIPTION ( " Amiga mouse driver " ) ;
MODULE_LICENSE ( " GPL " ) ;
static int amimouse_lastx , amimouse_lasty ;
2009-04-05 13:11:28 +02:00
static irqreturn_t amimouse_interrupt ( int irq , void * data )
2005-04-16 15:20:36 -07:00
{
2009-04-05 13:11:28 +02:00
struct input_dev * dev = data ;
2005-04-16 15:20:36 -07:00
unsigned short joy0dat , potgor ;
int nx , ny , dx , dy ;
2006-01-12 01:06:12 -08:00
joy0dat = amiga_custom . joy0dat ;
2005-04-16 15:20:36 -07:00
nx = joy0dat & 0xff ;
ny = joy0dat > > 8 ;
dx = nx - amimouse_lastx ;
dy = ny - amimouse_lasty ;
if ( dx < - 127 ) dx = ( 256 + nx ) - amimouse_lastx ;
if ( dx > 127 ) dx = ( nx - 256 ) - amimouse_lastx ;
if ( dy < - 127 ) dy = ( 256 + ny ) - amimouse_lasty ;
if ( dy > 127 ) dy = ( ny - 256 ) - amimouse_lasty ;
amimouse_lastx = nx ;
amimouse_lasty = ny ;
2006-01-12 01:06:12 -08:00
potgor = amiga_custom . potgor ;
2005-04-16 15:20:36 -07:00
2009-04-05 13:11:28 +02:00
input_report_rel ( dev , REL_X , dx ) ;
input_report_rel ( dev , REL_Y , dy ) ;
2005-04-16 15:20:36 -07:00
2009-04-05 13:11:28 +02:00
input_report_key ( dev , BTN_LEFT , ciaa . pra & 0x40 ) ;
input_report_key ( dev , BTN_MIDDLE , potgor & 0x0100 ) ;
input_report_key ( dev , BTN_RIGHT , potgor & 0x0400 ) ;
2005-04-16 15:20:36 -07:00
2009-04-05 13:11:28 +02:00
input_sync ( dev ) ;
2005-04-16 15:20:36 -07:00
return IRQ_HANDLED ;
}
static int amimouse_open ( struct input_dev * dev )
{
unsigned short joy0dat ;
2009-04-05 13:11:28 +02:00
int error ;
2005-04-16 15:20:36 -07:00
2006-01-12 01:06:12 -08:00
joy0dat = amiga_custom . joy0dat ;
2005-04-16 15:20:36 -07:00
amimouse_lastx = joy0dat & 0xff ;
amimouse_lasty = joy0dat > > 8 ;
2009-04-05 13:11:28 +02:00
error = request_irq ( IRQ_AMIGA_VERTB , amimouse_interrupt , 0 , " amimouse " ,
dev ) ;
if ( error )
dev_err ( & dev - > dev , " Can't allocate irq %d \n " , IRQ_AMIGA_VERTB ) ;
2005-04-16 15:20:36 -07:00
2009-04-05 13:11:28 +02:00
return error ;
2005-04-16 15:20:36 -07:00
}
static void amimouse_close ( struct input_dev * dev )
{
2009-04-05 13:11:28 +02:00
free_irq ( IRQ_AMIGA_VERTB , dev ) ;
2005-04-16 15:20:36 -07:00
}
2009-04-05 13:11:28 +02:00
static int __init amimouse_probe ( struct platform_device * pdev )
2005-04-16 15:20:36 -07:00
{
2006-11-05 22:40:19 -05:00
int err ;
2009-04-05 13:11:28 +02:00
struct input_dev * dev ;
2006-11-05 22:40:19 -05:00
2009-04-05 13:11:28 +02:00
dev = input_allocate_device ( ) ;
if ( ! dev )
2005-09-15 02:01:44 -05:00
return - ENOMEM ;
2009-04-05 13:11:28 +02:00
dev - > name = pdev - > name ;
dev - > phys = " amimouse/input0 " ;
dev - > id . bustype = BUS_AMIGA ;
dev - > id . vendor = 0x0001 ;
dev - > id . product = 0x0002 ;
dev - > id . version = 0x0100 ;
2005-04-16 15:20:36 -07:00
2009-04-05 13:11:28 +02:00
dev - > evbit [ 0 ] = BIT_MASK ( EV_KEY ) | BIT_MASK ( EV_REL ) ;
dev - > relbit [ 0 ] = BIT_MASK ( REL_X ) | BIT_MASK ( REL_Y ) ;
dev - > keybit [ BIT_WORD ( BTN_LEFT ) ] = BIT_MASK ( BTN_LEFT ) |
2007-10-18 23:40:32 -07:00
BIT_MASK ( BTN_MIDDLE ) | BIT_MASK ( BTN_RIGHT ) ;
2009-04-05 13:11:28 +02:00
dev - > open = amimouse_open ;
dev - > close = amimouse_close ;
dev - > dev . parent = & pdev - > dev ;
2005-04-16 15:20:36 -07:00
2009-04-05 13:11:28 +02:00
err = input_register_device ( dev ) ;
2006-11-05 22:40:19 -05:00
if ( err ) {
2009-04-05 13:11:28 +02:00
input_free_device ( dev ) ;
2006-11-05 22:40:19 -05:00
return err ;
}
2005-04-16 15:20:36 -07:00
2009-04-05 13:11:28 +02:00
platform_set_drvdata ( pdev , dev ) ;
2005-04-16 15:20:36 -07:00
return 0 ;
}
2009-04-05 13:11:28 +02:00
static int __exit amimouse_remove ( struct platform_device * pdev )
2005-04-16 15:20:36 -07:00
{
2009-04-05 13:11:28 +02:00
struct input_dev * dev = platform_get_drvdata ( pdev ) ;
platform_set_drvdata ( pdev , NULL ) ;
input_unregister_device ( dev ) ;
return 0 ;
}
static struct platform_driver amimouse_driver = {
. remove = __exit_p ( amimouse_remove ) ,
. driver = {
. name = " amiga-mouse " ,
. owner = THIS_MODULE ,
} ,
} ;
static int __init amimouse_init ( void )
{
return platform_driver_probe ( & amimouse_driver , amimouse_probe ) ;
2005-04-16 15:20:36 -07:00
}
module_init ( amimouse_init ) ;
2009-04-05 13:11:28 +02:00
static void __exit amimouse_exit ( void )
{
platform_driver_unregister ( & amimouse_driver ) ;
}
2005-04-16 15:20:36 -07:00
module_exit ( amimouse_exit ) ;
2009-04-05 13:11:28 +02:00
MODULE_ALIAS ( " platform:amiga-mouse " ) ;