⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vtplayer.c

📁 linux下的VTPplayer驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * VTPlayer mouse driver - 0.4.1 * * Copyright (c) 2004-2007 Christophe Jacquet <jacquetc@free.fr> * *	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, version 2. * * This driver is based on: *  - the usb-skeleton driver, version 1.1 *    copyright (c) 2001-2003 Greg Kroah-Hartman <greg@kroah.com> * *  - the usbmouse driver, version 1.15 *    copyright (c) 1999-2001 Vojtech Pavlik <vojtech@ucw.cz> * * * History: * * 2007-10-07 - 0.4.1 - adapted to SPARC (big-endian) architecture (ok with 2.6.22) * 2007-02-25 - 0.4.0 - adapted to changes in kernel APIs (ok with 2.6.15) * 2004-12-02 - 0.3.2 - changed device file display to "/dev/usb/vtplayer%d" * 2004-03-06 - 0.3.1 - lots of code cleanup - first public release * 2004-01-26 - 0.3.0 - merge of 0.1 and 0.2 - full support * 2004-01-26 - 0.2.0 - tactile cell support, written from usb-skeleton.c * 2004-01-25 - 0.1.0 - mouse support, based on usbmouse.c adapted to *                      VTPlayer's specific protocol * *//* * 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 */#include <linux/version.h>#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)	#include <linux/autoconf.h>#else	#include <linux/config.h>#endif#include <linux/kernel.h>#include <linux/errno.h>#include <linux/init.h>#include <linux/slab.h>#include <linux/module.h>#include <linux/moduleparam.h>#include <linux/smp_lock.h>#include <linux/completion.h>#include <asm/uaccess.h>#include <linux/usb.h>#include <linux/input.h>	/* this is an input driver, too */#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)#define SLAB_GFP_ATOMIC GFP_ATOMIC#else#define SLAB_GFP_ATOMIC SLAB_ATOMIC#endif#include "vtplayer.h"/* Use our own dbg macro */#undef dbg#define dbg(format, arg...) do { if (debug) printk(KERN_DEBUG __FILE__ ": " format "\n" , ## arg); } while (0)/* Version Information */#define DRIVER_VERSION "v0.4.0"#define DRIVER_AUTHOR "Christophe Jacquet <jacquetc@free.fr>"#define DRIVER_DESC "VirTouch VTPlayer Tactile Mouse Driver"/* Default minor base */#define VTP_MINOR_BASE	192/* Module parameters *//* Debug: print out additional debugging messages - off by default */static int debug = 0;module_param(debug, int, 0);MODULE_PARM_DESC(debug, "Debug enabled or not");/* VTPlayer vendor & product IDs */#define VTP_VENDOR_ID	0x1100#define VTP_PRODUCT_ID	0x0001/* table of devices that work with this driver */static struct usb_device_id vtp_table [] = {	{ USB_DEVICE(VTP_VENDOR_ID, VTP_PRODUCT_ID) },	{ }					/* Terminating entry */};MODULE_DEVICE_TABLE (usb, vtp_table);/* Structure to hold all of our device specific stuff */struct vtplayer {	struct usb_device *udev;			/* save off the usb device pointer */	struct usb_interface *interface; /* the interface for this device */	unsigned char minor;      /* the starting minor number for this device */	int open;                 /* if the port is open or not */	int present;              /* if the device is not disconnected */	struct semaphore sem;     /* locks this structure */	__u8 int_in_endpointAddr; /* the address of the interrupt in endpoint */	/* These fields are specifically for the input device */	struct input_dev *mouse_dev; /* associated input device */	struct urb *mouse_irq;       /* URB used for IRQ transferts */	int mouse_open;              /* if the input device is open or not */	signed char *mouse_data;     /* buffer containing data */	dma_addr_t mouse_data_dma;   /* DMA address */	char mouse_name[128];        /* device name */	char mouse_phys[64];         /* physical name */};/* prevent races between open() and disconnect() */static DECLARE_MUTEX (disconnect_sem);/* local function prototypes */static int vtp_ioctl		(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);static int vtp_open		(struct inode *inode, struct file *file);static int vtp_release		(struct inode *inode, struct file *file);static int vtp_probe		(struct usb_interface *interface, const struct usb_device_id *id);static void vtp_disconnect	(struct usb_interface *interface);#define VTP_DATA_LENGTH 4/************* I N P U T   D E V I C E   ( M O U S E ) ***********************/#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)static void vtp_mouse_irq(struct urb *urb, struct pt_regs *regs)#elsestatic void vtp_mouse_irq(struct urb *urb)#endif{	struct vtplayer *mouse = urb->context;	signed char *data = mouse->mouse_data;	struct input_dev *dev = mouse->mouse_dev;	int status;	switch (urb->status) {	case 0:			/* success */		break;	case -ECONNRESET:	/* unlink */	case -ENOENT:	case -ESHUTDOWN:		return;	/* -EPIPE:  should clear the halt */	default:		/* error */		goto resubmit;	}	#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)	input_regs(dev, regs);	#endif	/*	 * VTPlayer protocol (as reverse-engineered on 2004-01-22):	 *	byte 0		X motion	 *	byte 1		Y motion	 *	byte 2		unused (?)	 *	byte 3		button:	 *				1- right top	 *				2- right bottom	 *				4- left bottom	 *				8- left top	 */	input_report_key(dev, BTN_LEFT,   data[3] & 0x08);	input_report_key(dev, BTN_RIGHT,  data[3] & 0x01);	input_report_key(dev, BTN_MIDDLE, data[3] & 0x04);	input_report_key(dev, BTN_SIDE,   data[3] & 0x02);	input_report_rel(dev, REL_X,     data[0]);	input_report_rel(dev, REL_Y,     data[1]);	input_sync(dev);resubmit:	status = usb_submit_urb (urb, SLAB_GFP_ATOMIC);	if (status)		err ("can't resubmit intr, %s-%s/input0, status %d",				mouse->udev->bus->bus_name,				mouse->udev->devpath, status);}static int vtp_mouse_open(struct input_dev *dev){	struct vtplayer *mouse = dev->private;	dbg("%s", __FUNCTION__);	if (mouse->mouse_open++)		return 0;	mouse->mouse_irq->dev = mouse->udev;	if (usb_submit_urb(mouse->mouse_irq, GFP_KERNEL)) {		mouse->mouse_open--;		return -EIO;	}	return 0;}static void vtp_mouse_close(struct input_dev *dev){	struct vtplayer *mouse = dev->private;	dbg("%s", __FUNCTION__);	if (!--mouse->mouse_open)		usb_unlink_urb(mouse->mouse_irq);}/********************** T A C T I L E   P A D S ******************************//* * File operations needed when we register this driver. * This assumes that this driver NEEDS file operations, * of course, which means that the driver is expected * to have a node in the /dev directory. If the USB * device were for a network interface then the driver * would use "struct net_driver" instead, and a serial * device would use "struct tty_driver". */static struct file_operations vtp_fops = {	/*	 * The owner field is part of the module-locking	 * mechanism. The idea is that the kernel knows	 * which module to increment the use-counter of	 * BEFORE it calls the device's open() function.	 * This also means that the kernel can decrement	 * the use-counter again before calling release()	 * or should the open() function fail.	 */	.owner =	THIS_MODULE,	.ioctl =	vtp_ioctl,	.open =		vtp_open,	.release =	vtp_release,};/*  * usb class driver info in order to get a minor number from the usb core, * and to have the device registered with devfs and the driver core. * NOTE: the "mode" field has been removed from the structure since 2.6.15 */static struct usb_class_driver vtp_class = {	.name =		"vtplayer%d",	.fops =		&vtp_fops,	.minor_base =	VTP_MINOR_BASE,};/* usb specific object needed to register this driver with the usb subsystem */static struct usb_driver vtp_driver = {	#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)	.owner =	THIS_MODULE,	#endif	.name =		"vtplayer",	.probe =	vtp_probe,	.disconnect =	vtp_disconnect,	.id_table =	vtp_table,};/** *	vtp_delete */static inline void vtp_delete (struct vtplayer *dev){/*	if (dev->bulk_in_buffer != NULL)		kfree (dev->bulk_in_buffer);	if (dev->bulk_out_buffer != NULL)		usb_buffer_free (dev->udev, dev->bulk_out_size,				dev->bulk_out_buffer,				dev->write_urb->transfer_dma);*/	kfree (dev);}/** *	vtp_open */static int vtp_open (struct inode *inode, struct file *file){	struct vtplayer *dev = NULL;	struct usb_interface *interface;	int subminor;	int retval = 0;	dbg("%s", __FUNCTION__);	subminor = iminor(inode);	/* prevent disconnects */	down (&disconnect_sem);	interface = usb_find_interface (&vtp_driver, subminor);	if (!interface) {		err ("%s - error, can't find device for minor %d",		     __FUNCTION__, subminor);		retval = -ENODEV;		goto exit_no_device;	}	dev = usb_get_intfdata(interface);	if (!dev) {		retval = -ENODEV;		goto exit_no_device;	}	/* lock this device */	down (&dev->sem);	/* increment our usage count for the driver */	++dev->open;	/* save our object in the file's private structure */	file->private_data = dev;	/* unlock this device */	up (&dev->sem);exit_no_device:	up (&disconnect_sem);	return retval;}/** *	vtp_release */static int vtp_release (struct inode *inode, struct file *file){	struct vtplayer *dev;	int retval = 0;	dev = (struct vtplayer *)file->private_data;	if (dev == NULL) {		dbg ("%s: object is NULL", __FUNCTION__);		return -ENODEV;	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -