/* * mousek.c, sample code for USB drivers, heavily based on usbmouse.c * * Copyright (c) 2016 Kush Kumar Sharma * Copyright (c) 2000 Alessandro Rubini * Copyright (c) 1999 Vojtech Pavlik * */ /* * 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 */ #ifndef __KERNEL__ # define __KERNEL__ #endif #ifndef MODULE # define MODULE #endif #include #include #include #include #include #include /* usb stuff */ #include #include /* miscdevice stuff */ #include #include #include /* * Version Information */ #define DRIVER_VERSION "v0.1" #define DRIVER_AUTHOR "Kush Kumar Sharma" #define DRIVER_DESC "Mouse driver" #define DRIVER_LICENSE "GPL" MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE(DRIVER_LICENSE); #define DEVICE_NAME "mousek" int Major; struct mousek_device { signed char data[3]; /* use a three-byte protocol */ struct urb urb; /* USB Request block, to get USB data*/ struct input_dev *idev; /* input device, to push out input data */ int x, y; /* keep track of the position of this device */ }; static struct mousek_device *mouse; int mousek_open(struct inode *inode, struct file *filp) { /* announce yourself */ printk(KERN_INFO "mousek: faking an USB mouse via the misc device\n"); return 0; /* Ok */ } int mousek_release(struct inode *inode, struct file *filp) { printk(KERN_INFO "mousek: closing misc device\n"); return 0; } ssize_t mousek_read(struct file *filp, /* see include/linux/fs.h */ char *buffer, /* buffer to fill with data */ size_t length, /* length of the buffer */ loff_t * offset) { printk(KERN_INFO "mousek: Restricted. That is okay but do not repeat this mistake.\n"); return 0; } ssize_t mousek_write(struct file *filp, const char *buf, size_t count, loff_t *offp) { static char localbuf[16]; int i; /* accept 16 bytes at a time, at most */ if (count >16) count=16; copy_from_user(localbuf, buf, count); struct input_dev *dev = mouse->idev; /* scan written data */ for (i=0; idata[1] = mouse->data[2] = 0; switch (localbuf[i]) { case 'u': case 'U': /* up */ mouse->data[2] = -10; break; case 'd': case 'D': /* down */ mouse->data[2] = 10; break; case 'l': case 'L': /* left */ mouse->data[1] = -10; break; case 'r': case 'R': /* right */ mouse->data[1] = 10; break; default: continue; } input_report_key(dev, BTN_RIGHT, 1); input_report_key(dev, BTN_RIGHT, 0); input_report_key(dev, KEY_UP, 1); /* keypress */ input_report_key(dev, KEY_UP, 0); /* release */ input_report_rel(dev, REL_X, 30); input_report_rel(dev, REL_Y, 30); printk(KERN_ALERT "mousek: Control actions of %s received %d %d",localbuf, mouse->data[1], mouse->data[2]); } //input_report_rel(mouse->idev, REL_WHEEL, data[3]); input_sync(dev); return count; } struct file_operations mousek_fops = { write: mousek_write, read: mousek_read, open: mousek_open, release: mousek_release, }; int init_module(void) { int retval; Major = register_chrdev(0, DEVICE_NAME, &mousek_fops); if (Major < 0) { printk(KERN_ALERT "Registering char device failed with %d\n", Major); return Major; } struct input_dev *input_dev; /* allocate and zero a new data structure for the new device */ mouse = kmalloc(sizeof(struct mousek_device), GFP_KERNEL); if (!mouse) return -ENOMEM; /* failure */ memset(mouse, 0, sizeof(*mouse)); input_dev = input_allocate_device(); if (!input_dev) { printk(KERN_ERR "mousek.c: Not enough memory\n"); retval = -ENOMEM; //goto err_free_irq; } //updating struct mouse->idev = input_dev; input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); set_bit(103, input_dev->keybit); /* Up */ input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE); input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); retval = input_register_device(input_dev); if (retval) { printk(KERN_ERR "mousek: Failed to register device\n"); goto err_free_dev; } printk(KERN_INFO "I was assigned major number %d. To talk to\n", Major); printk(KERN_INFO "the driver, create a dev file with\n"); printk(KERN_INFO "'mknod /dev/%s c %d 0'.\n", DEVICE_NAME, Major); printk(KERN_INFO "Try various minor numbers. Try to cat and echo to\n"); printk(KERN_INFO "the device file.\n"); printk(KERN_INFO "Remove the device file and module when done.\n"); return 0; err_free_dev: input_free_device(mouse->idev); kfree(mouse); return retval; } void cleanup_module(void) { if(!mouse) return; input_unregister_device(mouse->idev); kfree(mouse); unregister_chrdev(Major, DEVICE_NAME); printk(KERN_ALERT "Uninstalled. Delete device from dev."); }