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

📄 wacom.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *  USB Wacom Graphire and Wacom Intuos tablet support * *  Copyright (c) 2000-2004 Vojtech Pavlik	<vojtech@ucw.cz> *  Copyright (c) 2000 Andreas Bach Aaen	<abach@stofanet.dk> *  Copyright (c) 2000 Clifford Wolf		<clifford@clifford.at> *  Copyright (c) 2000 Sam Mosel		<sam.mosel@computer.org> *  Copyright (c) 2000 James E. Blair		<corvus@gnu.org> *  Copyright (c) 2000 Daniel Egger		<egger@suse.de> *  Copyright (c) 2001 Frederic Lepied		<flepied@mandrakesoft.com> *  Copyright (c) 2004 Panagiotis Issaris	<panagiotis.issaris@mech.kuleuven.ac.be> *  Copyright (c) 2002-2005 Ping Cheng		<pingc@wacom.com> * *  ChangeLog: *      v0.1 (vp)  - Initial release *      v0.2 (aba) - Support for all buttons / combinations *      v0.3 (vp)  - Support for Intuos added *	v0.4 (sm)  - Support for more Intuos models, menustrip *			relative mode, proximity. *	v0.5 (vp)  - Big cleanup, nifty features removed, *			they belong in userspace *	v1.8 (vp)  - Submit URB only when operating, moved to CVS, *			use input_report_key instead of report_btn and *			other cleanups *	v1.11 (vp) - Add URB ->dev setting for new kernels *	v1.11 (jb) - Add support for the 4D Mouse & Lens *	v1.12 (de) - Add support for two more inking pen IDs *	v1.14 (vp) - Use new USB device id probing scheme. *		     Fix Wacom Graphire mouse wheel *	v1.18 (vp) - Fix mouse wheel direction *		     Make mouse relative *      v1.20 (fl) - Report tool id for Intuos devices *                 - Multi tools support *                 - Corrected Intuos protocol decoding (airbrush, 4D mouse, lens cursor...) *                 - Add PL models support *		   - Fix Wacom Graphire mouse wheel again *	v1.21 (vp) - Removed protocol descriptions *		   - Added MISC_SERIAL for tool serial numbers *	      (gb) - Identify version on module load. *    v1.21.1 (fl) - added Graphire2 support *    v1.21.2 (fl) - added Intuos2 support *                 - added all the PL ids *    v1.21.3 (fl) - added another eraser id from Neil Okamoto *                 - added smooth filter for Graphire from Peri Hankey *                 - added PenPartner support from Olaf van Es *                 - new tool ids from Ole Martin Bjoerndalen *	v1.29 (pc) - Add support for more tablets *		   - Fix pressure reporting *	v1.30 (vp) - Merge 2.4 and 2.5 drivers *		   - Since 2.5 now has input_sync(), remove MSC_SERIAL abuse *		   - Cleanups here and there *    v1.30.1 (pi) - Added Graphire3 support *	v1.40 (pc) - Add support for several new devices, fix eraser reporting, ... *	v1.43 (pc) - Added support for Cintiq 21UX *		   - Fixed a Graphire bug *		   - Merged wacom_intuos3_irq into wacom_intuos_irq *	v1.44 (pc) - Added support for Graphire4, Cintiq 710, Intuos3 6x11, etc. *		   - Report Device IDs *//* * 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. */#include <linux/kernel.h>#include <linux/slab.h>#include <linux/input.h>#include <linux/module.h>#include <linux/init.h>#include <linux/usb.h>#include <linux/usb_input.h>#include <asm/unaligned.h>#include <asm/byteorder.h>/* * Version Information */#define DRIVER_VERSION "v1.44"#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>"#define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver"#define DRIVER_LICENSE "GPL"MODULE_AUTHOR(DRIVER_AUTHOR);MODULE_DESCRIPTION(DRIVER_DESC);MODULE_LICENSE(DRIVER_LICENSE);#define USB_VENDOR_ID_WACOM	0x056a#define STYLUS_DEVICE_ID	0x02#define CURSOR_DEVICE_ID	0x06#define ERASER_DEVICE_ID	0x0Aenum {	PENPARTNER = 0,	GRAPHIRE,	G4,	PL,	INTUOS,	INTUOS3,	CINTIQ,	MAX_TYPE};struct wacom_features {	char *name;	int pktlen;	int x_max;	int y_max;	int pressure_max;	int distance_max;	int type;	usb_complete_t irq;};struct wacom {	signed char *data;	dma_addr_t data_dma;	struct input_dev *dev;	struct usb_device *usbdev;	struct urb *irq;	struct wacom_features *features;	int tool[2];	int id[2];	__u32 serial[2];	char phys[32];};#define USB_REQ_SET_REPORT	0x09static int usb_set_report(struct usb_interface *intf, unsigned char type,				unsigned char id, void *buf, int size){	return usb_control_msg(interface_to_usbdev(intf),		usb_sndctrlpipe(interface_to_usbdev(intf), 0),                USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE,                (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber,		buf, size, 1000);}static void wacom_pl_irq(struct urb *urb, struct pt_regs *regs){	struct wacom *wacom = urb->context;	unsigned char *data = wacom->data;	struct input_dev *dev = wacom->dev;	int prox, pressure, id;	int retval;	switch (urb->status) {	case 0:		/* success */		break;	case -ECONNRESET:	case -ENOENT:	case -ESHUTDOWN:		/* this urb is terminated, clean up */		dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);		return;	default:		dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);		goto exit;	}	if (data[0] != 2) {		dbg("wacom_pl_irq: received unknown report #%d", data[0]);		goto exit;	}	prox = data[1] & 0x40;	input_regs(dev, regs);	id = ERASER_DEVICE_ID;	if (prox) {		pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1));		if (wacom->features->pressure_max > 255)			pressure = (pressure << 1) | ((data[4] >> 6) & 1);		pressure += (wacom->features->pressure_max + 1) / 2;		/*		 * if going from out of proximity into proximity select between the eraser		 * and the pen based on the state of the stylus2 button, choose eraser if		 * pressed else choose pen. if not a proximity change from out to in, send		 * an out of proximity for previous tool then a in for new tool.		 */		if (!wacom->tool[0]) {			/* Eraser bit set for DTF */			if (data[1] & 0x10)				wacom->tool[1] = BTN_TOOL_RUBBER;			else				/* Going into proximity select tool */				wacom->tool[1] = (data[4] & 0x20) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;		} else {			/* was entered with stylus2 pressed */			if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[4] & 0x20)) {				/* report out proximity for previous tool */				input_report_key(dev, wacom->tool[1], 0);				input_sync(dev);				wacom->tool[1] = BTN_TOOL_PEN;				goto exit;			}		}		if (wacom->tool[1] != BTN_TOOL_RUBBER) {			/* Unknown tool selected default to pen tool */			wacom->tool[1] = BTN_TOOL_PEN;			id = STYLUS_DEVICE_ID;		}		input_report_key(dev, wacom->tool[1], id); /* report in proximity for tool */		input_report_abs(dev, ABS_X, data[3] | (data[2] << 7) | ((data[1] & 0x03) << 14));		input_report_abs(dev, ABS_Y, data[6] | (data[5] << 7) | ((data[4] & 0x03) << 14));		input_report_abs(dev, ABS_PRESSURE, pressure);		input_report_key(dev, BTN_TOUCH, data[4] & 0x08);		input_report_key(dev, BTN_STYLUS, data[4] & 0x10);		/* Only allow the stylus2 button to be reported for the pen tool. */		input_report_key(dev, BTN_STYLUS2, (wacom->tool[1] == BTN_TOOL_PEN) && (data[4] & 0x20));	} else {		/* report proximity-out of a (valid) tool */		if (wacom->tool[1] != BTN_TOOL_RUBBER) {			/* Unknown tool selected default to pen tool */			wacom->tool[1] = BTN_TOOL_PEN;		}		input_report_key(dev, wacom->tool[1], prox);	}	wacom->tool[0] = prox; /* Save proximity state */	input_sync(dev); exit:	retval = usb_submit_urb (urb, GFP_ATOMIC);	if (retval)		err ("%s - usb_submit_urb failed with result %d",		     __FUNCTION__, retval);}static void wacom_ptu_irq(struct urb *urb, struct pt_regs *regs){	struct wacom *wacom = urb->context;	unsigned char *data = wacom->data;	struct input_dev *dev = wacom->dev;	int retval;	switch (urb->status) {	case 0:		/* success */		break;	case -ECONNRESET:	case -ENOENT:	case -ESHUTDOWN:		/* this urb is terminated, clean up */		dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);		return;	default:		dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);		goto exit;	}	if (data[0] != 2) {		printk(KERN_INFO "wacom_ptu_irq: received unknown report #%d\n", data[0]);		goto exit;	}	input_regs(dev, regs);	if (data[1] & 0x04) {		input_report_key(dev, BTN_TOOL_RUBBER, (data[1] & 0x20) ? ERASER_DEVICE_ID : 0);		input_report_key(dev, BTN_TOUCH, data[1] & 0x08);	} else {		input_report_key(dev, BTN_TOOL_PEN, (data[1] & 0x20) ? STYLUS_DEVICE_ID : 0);		input_report_key(dev, BTN_TOUCH, data[1] & 0x01);	}	input_report_abs(dev, ABS_X, le16_to_cpu(*(__le16 *) &data[2]));	input_report_abs(dev, ABS_Y, le16_to_cpu(*(__le16 *) &data[4]));	input_report_abs(dev, ABS_PRESSURE, le16_to_cpu(*(__le16 *) &data[6]));	input_report_key(dev, BTN_STYLUS, data[1] & 0x02);	input_report_key(dev, BTN_STYLUS2, data[1] & 0x10);	input_sync(dev); exit:	retval = usb_submit_urb (urb, GFP_ATOMIC);	if (retval)		err ("%s - usb_submit_urb failed with result %d",		     __FUNCTION__, retval);}static void wacom_penpartner_irq(struct urb *urb, struct pt_regs *regs){	struct wacom *wacom = urb->context;	unsigned char *data = wacom->data;	struct input_dev *dev = wacom->dev;	int retval;	switch (urb->status) {	case 0:		/* success */		break;	case -ECONNRESET:	case -ENOENT:	case -ESHUTDOWN:		/* this urb is terminated, clean up */		dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);		return;	default:		dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);		goto exit;	}	if (data[0] != 2) {		printk(KERN_INFO "wacom_penpartner_irq: received unknown report #%d\n", data[0]);		goto exit;	}	input_regs(dev, regs);	input_report_key(dev, BTN_TOOL_PEN, STYLUS_DEVICE_ID);	input_report_abs(dev, ABS_X, le16_to_cpu(*(__le16 *) &data[1]));	input_report_abs(dev, ABS_Y, le16_to_cpu(*(__le16 *) &data[3]));	input_report_abs(dev, ABS_PRESSURE, (signed char)data[6] + 127);	input_report_key(dev, BTN_TOUCH, ((signed char)data[6] > -80) && !(data[5] & 0x20));	input_report_key(dev, BTN_STYLUS, (data[5] & 0x40));	input_sync(dev); exit:	retval = usb_submit_urb (urb, GFP_ATOMIC);

⌨️ 快捷键说明

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