Hi all
I want to write a virtual PS/2 mouse driver to hook to the input core,
after I load the driver
The psmouse input device driver probes my virtual device as a “Generic
PS/2 mouse” in /dev/input/mouse1
And sent a F4 (mouse enable command) to my pseudo device.
I use a user space program to send the following mouse movement packet
and launch
gpm –m /dev/input/mouse1 –t ps2
but when I run the user space program , there is no mouse movement
event occurred,
is there anything wrong with my code using serio_interrupt () ?
#include <fcntl.h>
int main()
{
int fd;
int x, y;
char buffer[10];
fd = open ("/sys/devices/platform/dummy/coordinates", O_RDWR);
if (fd < 0) {
perror ("open file");
exit (0);
}
while (1) {
x = random () % 20;
y = random () % 20;
sprintf (buffer, "%d", x, y);
write (fd, buffer, strlen(buffer));
fsync (fd);
sleep (1);
}
}
/*
* dummy mouse serio driver for linux
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/serio.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/spinlock.h>
#include <linux/err.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/system.h>
#include <linux/platform_device.h>
MODULE_AUTHOR("Wisecamera Corp.");
MODULE_DESCRIPTION("dummy ps2 mouse driver");
MODULE_LICENSE("GPL");
static struct serio *dummy_port;
static struct platform_device *dummy_device;
int port_num;
static ssize_t
write_vms (struct device *dev, struct device_attribute *attr, const
char *buffer, size_t count)
{
int x, y;
sscanf (buffer, "%x", &x);
serio_interrupt (dev, 0x8, 0 , NULL);
serio_interrupt (dev, x, NULL);
serio_interrupt (dev, y, 0, NULL);
serio_interrupt (dev, 0, 0, NULL);
return count;
}
/* Attach the sysgs write method */
DEVICE_ATTR (coordinates, 0644, NULL, write_vms);
static struct attribute *vms_attrs [] = {
&dev_attr_coordinates.attr,
NULL
};
static struct attribute_group vms_attr_group = {
.attrs = vms_attrs,
};
static int dummy_open (struct serio *dev)
{
printk ("dummy open\n");
serio_interrupt (dev, 0xaa, 0, NULL);
serio_interrupt (dev, 0x00, 0, NULL);
return 0;
}
static int dummy_write (struct serio *dev, unsigned char val)
{
printk ("dummy write %x\n", val);
switch (val) {
case 0xf2:
serio_interrupt (dev, 0xfa, 0, NULL);
serio_interrupt (dev, 0x00, 0, NULL);
break;
default:
serio_interrupt (dev, 0xfa, 0, NULL);
}
return 0;
}
static void dummy_close (struct serio *dev)
{
printk ("dummy close\n");
return;
}
static struct serio * __init dummy_allocate_port (void *port_data,
char *name, char *phys)
{
struct serio *serio;
serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
if (serio)
{
memset(serio, 0, sizeof(struct serio));
serio->id.type = SERIO_8042;
serio->write = dummy_write;
serio->open = dummy_open;
serio->close = dummy_close;
snprintf(serio->name, sizeof(serio->name), name);
snprintf(serio->phys, sizeof(serio->phys), phys);
serio->port_data = NULL;
serio->dev.parent = &dummy_device->dev;
}
return serio;
}
static void __exit dummy_exit (void)
{
sysfs_remove_group (&dummy_device->dev.kobj, &vms_attr_group);
serio_unregister_port(dummy_port);
platform_device_unregister(dummy_device);
}
static int __init dummy_init (void)
{
char phys[20];
char name[20];
dummy_device = platform_device_register_simple("dummy", -1,
NULL, 0);
if (IS_ERR(dummy_device))
return PTR_ERR(dummy_device);
sysfs_create_group (&dummy_device->dev.kobj, &vms_attr_group);
sprintf(name, "dummy PS2 mouse port");
sprintf(phys, "dummy/serio%d", 0);
if ((dummy_port = dummy_allocate_port(NULL, name, phys)) ==
NULL)
{
dummy_exit();
return -1;
}
/* register port */
serio_register_port(dummy_port);
return 0;
}
module_init(dummy_init);
module_exit(dummy_exit);
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html