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

📄 aiptek.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
/* *  Native support for the Aiptek HyperPen USB Tablets *  (4000U/5000U/6000U/8000U/12000U) * *  Copyright (c) 2001      Chris Atenasio   <chris@crud.net> *  Copyright (c) 2002-2004 Bryan W. Headley <bwheadley@earthlink.net> * *  based on wacom.c by *     Vojtech Pavlik      <vojtech@suse.cz> *     Andreas Bach Aaen   <abach@stofanet.dk> *     Clifford Wolf       <clifford@clifford.at> *     Sam Mosel           <sam.mosel@computer.org> *     James E. Blair      <corvus@gnu.org> *     Daniel Egger        <egger@suse.de> * *  Many thanks to Oliver Kuechemann for his support. * *  ChangeLog: *      v0.1 - Initial release *      v0.2 - Hack to get around fake event 28's. (Bryan W. Headley) *      v0.3 - Make URB dynamic (Bryan W. Headley, Jun-8-2002) *             Released to Linux 2.4.19 and 2.5.x *      v0.4 - Rewrote substantial portions of the code to deal with *             corrected control sequences, timing, dynamic configuration, *             support of 6000U - 12000U, procfs, and macro key support *             (Jan-1-2003 - Feb-5-2003, Bryan W. Headley) *      v1.0 - Added support for diagnostic messages, count of messages *             received from URB - Mar-8-2003, Bryan W. Headley *      v1.1 - added support for tablet resolution, changed DV and proximity *             some corrections - Jun-22-2003, martin schneebacher *           - Added support for the sysfs interface, deprecating the *             procfs interface for 2.5.x kernel. Also added support for *             Wheel command. Bryan W. Headley July-15-2003. *      v1.2 - Reworked jitter timer as a kernel thread. *             Bryan W. Headley November-28-2003/Jan-10-2004. *      v1.3 - Repaired issue of kernel thread going nuts on single-processor *             machines, introduced programmableDelay as a command line *             parameter. Feb 7 2004, Bryan W. Headley. *      v1.4 - Re-wire jitter so it does not require a thread. Courtesy of *             Rene van Paassen. Added reporting of physical pointer device *             (e.g., stylus, mouse in reports 2, 3, 4, 5. We don't know *             for reports 1, 6.) *             what physical device reports for reports 1, 6.) Also enabled *             MOUSE and LENS tool button modes. Renamed "rubber" to "eraser". *             Feb 20, 2004, Bryan W. Headley. *      v1.5 - Added previousJitterable, so we don't do jitter delay when the *             user is holding a button down for periods of time. * * NOTE: *      This kernel driver is augmented by the "Aiptek" XFree86 input *      driver for your X server, as well as the Gaiptek GUI Front-end *      "Tablet Manager". *      These three products are highly interactive with one another, *      so therefore it's easier to document them all as one subsystem. *      Please visit the project's "home page", located at, *      http://aiptektablet.sourceforge.net. * * 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/jiffies.h>#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 <linux/sched.h>#include <asm/uaccess.h>#include <asm/unaligned.h>/* * Version Information */#define DRIVER_VERSION "v1.5 (May-15-2004)"#define DRIVER_AUTHOR  "Bryan W. Headley/Chris Atenasio"#define DRIVER_DESC    "Aiptek HyperPen USB Tablet Driver (Linux 2.6.x)"/* * Aiptek status packet: * * (returned as Report 1 - relative coordinates from mouse and stylus) * *        bit7  bit6  bit5  bit4  bit3  bit2  bit1  bit0 * byte0   0     0     0     0     0     0     0     1 * byte1   0     0     0     0     0    BS2   BS    Tip * byte2  X7    X6    X5    X4    X3    X2    X1    X0 * byte3  Y7    Y6    Y5    Y4    Y3    Y2    Y1    Y0 * * (returned as Report 2 - absolute coordinates from the stylus) * *        bit7  bit6  bit5  bit4  bit3  bit2  bit1  bit0 * byte0   0     0     0     0     0     0     1     0 * byte1  X7    X6    X5    X4    X3    X2    X1    X0 * byte2  X15   X14   X13   X12   X11   X10   X9    X8 * byte3  Y7    Y6    Y5    Y4    Y3    Y2    Y1    Y0 * byte4  Y15   Y14   Y13   Y12   Y11   Y10   Y9    Y8 * byte5   *     *     *    BS2   BS1   Tip   IR    DV * byte6  P7    P6    P5    P4    P3    P2    P1    P0 * byte7  P15   P14   P13   P12   P11   P10   P9    P8 * * (returned as Report 3 - absolute coordinates from the mouse) * *        bit7  bit6  bit5  bit4  bit3  bit2  bit1  bit0 * byte0   0     0     0     0     0     0     1     0 * byte1  X7    X6    X5    X4    X3    X2    X1    X0 * byte2  X15   X14   X13   X12   X11   X10   X9    X8 * byte3  Y7    Y6    Y5    Y4    Y3    Y2    Y1    Y0 * byte4  Y15   Y14   Y13   Y12   Y11   Y10   Y9    Y8 * byte5   *     *     *    BS2   BS1   Tip   IR    DV * byte6  P7    P6    P5    P4    P3    P2    P1    P0 * byte7  P15   P14   P13   P12   P11   P10   P9    P8 * * (returned as Report 4 - macrokeys from the stylus) * *        bit7  bit6  bit5  bit4  bit3  bit2  bit1  bit0 * byte0   0     0     0     0     0     1     0     0 * byte1   0     0     0    BS2   BS    Tip   IR    DV * byte2   0     0     0     0     0     0     1     0 * byte3   0     0     0    K4    K3    K2    K1    K0 * byte4  P7    P6    P5    P4    P3    P2    P1    P0 * byte5  P15   P14   P13   P12   P11   P10   P9    P8 * * (returned as Report 5 - macrokeys from the mouse) * *        bit7  bit6  bit5  bit4  bit3  bit2  bit1  bit0 * byte0   0     0     0     0     0     1     0     0 * byte1   0     0     0    BS2   BS    Tip   IR    DV * byte2   0     0     0     0     0     0     1     0 * byte3   0     0     0    K4    K3    K2    K1    K0 * byte4  P7    P6    P5    P4    P3    P2    P1    P0 * byte5  P15   P14   P13   P12   P11   P10   P9    P8 * * IR: In Range = Proximity on * DV = Data Valid * BS = Barrel Switch (as in, macro keys) * BS2 also referred to as Tablet Pick * * Command Summary: * * Use report_type CONTROL (3) * Use report_id   2 * * Command/Data    Description     Return Bytes    Return Value * 0x10/0x00       SwitchToMouse       0 * 0x10/0x01       SwitchToTablet      0 * 0x18/0x04       SetResolution       0 * 0x12/0xFF       AutoGainOn          0 * 0x17/0x00       FilterOn            0 * 0x01/0x00       GetXExtension       2           MaxX * 0x01/0x01       GetYExtension       2           MaxY * 0x02/0x00       GetModelCode        2           ModelCode = LOBYTE * 0x03/0x00       GetODMCode          2           ODMCode * 0x08/0x00       GetPressureLevels   2           =512 * 0x04/0x00       GetFirmwareVersion  2           Firmware Version * 0x11/0x02       EnableMacroKeys     0 * * To initialize the tablet: * * (1) Send Resolution500LPI (Command) * (2) Query for Model code (Option Report) * (3) Query for ODM code (Option Report) * (4) Query for firmware (Option Report) * (5) Query for GetXExtension (Option Report) * (6) Query for GetYExtension (Option Report) * (7) Query for GetPressureLevels (Option Report) * (8) SwitchToTablet for Absolute coordinates, or *     SwitchToMouse for Relative coordinates (Command) * (9) EnableMacroKeys (Command) * (10) FilterOn (Command) * (11) AutoGainOn (Command) * * (Step 9 can be omitted, but you'll then have no function keys.) */#define USB_VENDOR_ID_AIPTEK				0x08ca#define USB_REQ_GET_REPORT				0x01#define USB_REQ_SET_REPORT				0x09	/* PointerMode codes	 */#define AIPTEK_POINTER_ONLY_MOUSE_MODE			0#define AIPTEK_POINTER_ONLY_STYLUS_MODE			1#define AIPTEK_POINTER_EITHER_MODE			2#define AIPTEK_POINTER_ALLOW_MOUSE_MODE(a)		\	(a == AIPTEK_POINTER_ONLY_MOUSE_MODE ||		\	 a == AIPTEK_POINTER_EITHER_MODE)#define AIPTEK_POINTER_ALLOW_STYLUS_MODE(a)		\	(a == AIPTEK_POINTER_ONLY_STYLUS_MODE ||	\	 a == AIPTEK_POINTER_EITHER_MODE)	/* CoordinateMode code	 */#define AIPTEK_COORDINATE_RELATIVE_MODE			0#define AIPTEK_COORDINATE_ABSOLUTE_MODE			1       /* XTilt and YTilt values        */#define AIPTEK_TILT_MIN					(-128)#define AIPTEK_TILT_MAX					127#define AIPTEK_TILT_DISABLE				(-10101)	/* Wheel values	 */#define AIPTEK_WHEEL_MIN				0#define AIPTEK_WHEEL_MAX				1024#define AIPTEK_WHEEL_DISABLE				(-10101)	/* ToolCode values, which BTW are 0x140 .. 0x14f	 * We have things set up such that if TOOL_BUTTON_FIRED_BIT is	 * not set, we'll send one instance of AIPTEK_TOOL_BUTTON_xxx.	 *	 * Whenever the user resets the value, TOOL_BUTTON_FIRED_BIT will	 * get reset.	 */#define TOOL_BUTTON(x)					((x) & 0x14f)#define TOOL_BUTTON_FIRED(x)				((x) & 0x200)#define TOOL_BUTTON_FIRED_BIT				0x200	/* toolMode codes	 */#define AIPTEK_TOOL_BUTTON_PEN_MODE			BTN_TOOL_PEN#define AIPTEK_TOOL_BUTTON_PEN_MODE			BTN_TOOL_PEN#define AIPTEK_TOOL_BUTTON_PENCIL_MODE			BTN_TOOL_PENCIL#define AIPTEK_TOOL_BUTTON_BRUSH_MODE			BTN_TOOL_BRUSH#define AIPTEK_TOOL_BUTTON_AIRBRUSH_MODE		BTN_TOOL_AIRBRUSH#define AIPTEK_TOOL_BUTTON_ERASER_MODE			BTN_TOOL_RUBBER#define AIPTEK_TOOL_BUTTON_MOUSE_MODE			BTN_TOOL_MOUSE#define AIPTEK_TOOL_BUTTON_LENS_MODE			BTN_TOOL_LENS	/* Diagnostic message codes	 */#define AIPTEK_DIAGNOSTIC_NA				0#define AIPTEK_DIAGNOSTIC_SENDING_RELATIVE_IN_ABSOLUTE	1#define AIPTEK_DIAGNOSTIC_SENDING_ABSOLUTE_IN_RELATIVE	2#define AIPTEK_DIAGNOSTIC_TOOL_DISALLOWED		3	/* Time to wait (in ms) to help mask hand jittering	 * when pressing the stylus buttons.	 */#define AIPTEK_JITTER_DELAY_DEFAULT			50	/* Time to wait (in ms) in-between sending the tablet	 * a command and beginning the process of reading the return	 * sequence from the tablet.	 */#define AIPTEK_PROGRAMMABLE_DELAY_25		25#define AIPTEK_PROGRAMMABLE_DELAY_50		50#define AIPTEK_PROGRAMMABLE_DELAY_100		100#define AIPTEK_PROGRAMMABLE_DELAY_200		200#define AIPTEK_PROGRAMMABLE_DELAY_300		300#define AIPTEK_PROGRAMMABLE_DELAY_400		400#define AIPTEK_PROGRAMMABLE_DELAY_DEFAULT	AIPTEK_PROGRAMMABLE_DELAY_400	/* Mouse button programming	 */#define AIPTEK_MOUSE_LEFT_BUTTON		0x01#define AIPTEK_MOUSE_RIGHT_BUTTON		0x02#define AIPTEK_MOUSE_MIDDLE_BUTTON		0x04	/* Stylus button programming	 */#define AIPTEK_STYLUS_LOWER_BUTTON		0x08#define AIPTEK_STYLUS_UPPER_BUTTON		0x10	/* Length of incoming packet from the tablet	 */#define AIPTEK_PACKET_LENGTH			8	/* We report in EV_MISC both the proximity and	 * whether the report came from the stylus, tablet mouse	 * or "unknown" -- Unknown when the tablet is in relative	 * mode, because we only get report 1's.	 */#define AIPTEK_REPORT_TOOL_UNKNOWN		0x10#define AIPTEK_REPORT_TOOL_STYLUS		0x20#define AIPTEK_REPORT_TOOL_MOUSE		0x40static int programmableDelay = AIPTEK_PROGRAMMABLE_DELAY_DEFAULT;static int jitterDelay = AIPTEK_JITTER_DELAY_DEFAULT;struct aiptek_features {	int odmCode;		/* Tablet manufacturer code       */	int modelCode;		/* Tablet model code (not unique) */	int firmwareCode;	/* prom/eeprom version            */	char usbPath[64 + 1];	/* device's physical usb path     */	char inputPath[64 + 1];	/* input device path              */};struct aiptek_settings {	int pointerMode;	/* stylus-, mouse-only or either */	int coordinateMode;	/* absolute/relative coords      */	int toolMode;		/* pen, pencil, brush, etc. tool */	int xTilt;		/* synthetic xTilt amount        */	int yTilt;		/* synthetic yTilt amount        */	int wheel;		/* synthetic wheel amount        */	int stylusButtonUpper;	/* stylus upper btn delivers...  */	int stylusButtonLower;	/* stylus lower btn delivers...  */	int mouseButtonLeft;	/* mouse left btn delivers...    */	int mouseButtonMiddle;	/* mouse middle btn delivers...  */	int mouseButtonRight;	/* mouse right btn delivers...   */	int programmableDelay;	/* delay for tablet programming  */	int jitterDelay;	/* delay for hand jittering      */};struct aiptek {	struct input_dev *inputdev;		/* input device struct           */	struct usb_device *usbdev;		/* usb device struct             */	struct urb *urb;			/* urb for incoming reports      */	dma_addr_t data_dma;			/* our dma stuffage              */	struct aiptek_features features;	/* tablet's array of features    */	struct aiptek_settings curSetting;	/* tablet's current programmable */	struct aiptek_settings newSetting;	/* ... and new param settings    */	unsigned int ifnum;			/* interface number for IO       */	int diagnostic;				/* tablet diagnostic codes       */	unsigned long eventCount;		/* event count                   */	int inDelay;				/* jitter: in jitter delay?      */	unsigned long endDelay;			/* jitter: time when delay ends  */	int previousJitterable;			/* jitterable prev value     */	unsigned char *data;			/* incoming packet data          */};/* * Permit easy lookup of keyboard events to send, versus * the bitmap which comes from the tablet. This hides the * issue that the F_keys are not sequentially numbered. */static int macroKeyEvents[] = {	KEY_ESC, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5,	KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_F11,	KEY_F12, KEY_F13, KEY_F14, KEY_F15, KEY_F16, KEY_F17,	KEY_F18, KEY_F19, KEY_F20, KEY_F21, KEY_F22, KEY_F23,	KEY_F24, KEY_STOP, KEY_AGAIN, KEY_PROPS, KEY_UNDO,	KEY_FRONT, KEY_COPY, KEY_OPEN, KEY_PASTE, 0};/*********************************************************************** * Relative reports deliver values in 2's complement format to * deal with negative offsets. */static int aiptek_convert_from_2s_complement(unsigned char c){	int ret;	unsigned char b = c;	int negate = 0;	if ((b & 0x80) != 0) {		b = ~b;		b--;		negate = 1;	}	ret = b;	ret = (negate == 1) ? -ret : ret;	return ret;}/*********************************************************************** * aiptek_irq can receive one of six potential reports. * The documentation for each is in the body of the function. * * The tablet reports on several attributes per invocation of * aiptek_irq. Because the Linux Input Event system allows the * transmission of ONE attribute per input_report_xxx() call, * collation has to be done on the other end to reconstitute * a complete tablet report. Further, the number of Input Event reports * submitted varies, depending on what USB report type, and circumstance. * To deal with this, EV_MSC is used to indicate an 'end-of-report' * message. This has been an undocumented convention understood by the kernel * tablet driver and clients such as gpm and XFree86's tablet drivers. * * Of the information received from the tablet, the one piece I * cannot transmit is the proximity bit (without resorting to an EV_MSC * convention above.) I therefore have taken over REL_MISC and ABS_MISC * (for relative and absolute reports, respectively) for communicating * Proximity. Why two events? I thought it interesting to know if the * Proximity event occurred while the tablet was in absolute or relative * mode. * * Other tablets use the notion of a certain minimum stylus pressure * to infer proximity. While that could have been done, that is yet * another 'by convention' behavior, the documentation for which * would be spread between two (or more) pieces of software. * * EV_MSC usage was terminated for this purpose in Linux 2.5.x, and * replaced with the input_sync() method (which emits EV_SYN.) */static void aiptek_irq(struct urb *urb, struct pt_regs *regs){	struct aiptek *aiptek = urb->context;	unsigned char *data = aiptek->data;	struct input_dev *inputdev = aiptek->inputdev;	int jitterable = 0;	int retval, macro, x, y, z, left, right, middle, p, dv, tip, bs, pck;	switch (urb->status) {	case 0:		/* Success */		break;	case -ECONNRESET:	case -ENOENT:

⌨️ 快捷键说明

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