problem of writing a virtual ps2 mouse driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [Linux Media Devel]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Linux Wireless Networking]     [Linux Omap]

  Powered by Linux