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

📄 aiptek.c

📁 h内核
💻 C
📖 第 1 页 / 共 5 页
字号:
	default:		dbg("%s - nonzero urb status received: %d",		    __FUNCTION__, urb->status);		goto exit;	}	/* See if we are in a delay loop -- throw out report if true.	 */	if (aiptek->inDelay == 1 && time_after(aiptek->endDelay, jiffies)) {		goto exit;	}	aiptek->inDelay = 0;	aiptek->eventCount++;	/* Report 1 delivers relative coordinates with either a stylus	 * or the mouse. You do not know, however, which input	 * tool generated the event.	 */	if (data[0] == 1) {		if (aiptek->curSetting.coordinateMode ==		    AIPTEK_COORDINATE_ABSOLUTE_MODE) {			aiptek->diagnostic =			    AIPTEK_DIAGNOSTIC_SENDING_RELATIVE_IN_ABSOLUTE;		} else {			input_regs(inputdev, regs);			x = aiptek_convert_from_2s_complement(data[2]);			y = aiptek_convert_from_2s_complement(data[3]);			/* jitterable keeps track of whether any button has been pressed.			 * We're also using it to remap the physical mouse button mask			 * to pseudo-settings. (We don't specifically care about it's			 * value after moving/transposing mouse button bitmasks, except			 * that a non-zero value indicates that one or more			 * mouse button was pressed.)			 */			jitterable = data[5] & 0x07;			left = (data[5] & aiptek->curSetting.mouseButtonLeft) != 0 ? 1 : 0;			right = (data[5] & aiptek->curSetting.mouseButtonRight) != 0 ? 1 : 0;			middle = (data[5] & aiptek->curSetting.mouseButtonMiddle) != 0 ? 1 : 0;			input_report_key(inputdev, BTN_LEFT, left);			input_report_key(inputdev, BTN_MIDDLE, middle);			input_report_key(inputdev, BTN_RIGHT, right);			input_report_rel(inputdev, REL_X, x);			input_report_rel(inputdev, REL_Y, y);			input_report_rel(inputdev, REL_MISC, 1 | AIPTEK_REPORT_TOOL_UNKNOWN);			/* Wheel support is in the form of a single-event			 * firing.			 */			if (aiptek->curSetting.wheel != AIPTEK_WHEEL_DISABLE) {				input_report_rel(inputdev, REL_WHEEL,						 aiptek->curSetting.wheel);				aiptek->curSetting.wheel = AIPTEK_WHEEL_DISABLE;			}			input_sync(inputdev);		}	}	/* Report 2 is delivered only by the stylus, and delivers	 * absolute coordinates.	 */	else if (data[0] == 2) {		if (aiptek->curSetting.coordinateMode == AIPTEK_COORDINATE_RELATIVE_MODE) {			aiptek->diagnostic = AIPTEK_DIAGNOSTIC_SENDING_ABSOLUTE_IN_RELATIVE;		} else if (!AIPTEK_POINTER_ALLOW_STYLUS_MODE			    (aiptek->curSetting.pointerMode)) {				aiptek->diagnostic = AIPTEK_DIAGNOSTIC_TOOL_DISALLOWED;		} else {			input_regs(inputdev, regs);			x = le16_to_cpu(get_unaligned((__le16 *) (data + 1)));			y = le16_to_cpu(get_unaligned((__le16 *) (data + 3)));			z = le16_to_cpu(get_unaligned((__le16 *) (data + 6)));			p = (data[5] & 0x01) != 0 ? 1 : 0;			dv = (data[5] & 0x02) != 0 ? 1 : 0;			tip = (data[5] & 0x04) != 0 ? 1 : 0;			/* Use jitterable to re-arrange button masks			 */			jitterable = data[5] & 0x18;			bs = (data[5] & aiptek->curSetting.stylusButtonLower) != 0 ? 1 : 0;			pck = (data[5] & aiptek->curSetting.stylusButtonUpper) != 0 ? 1 : 0;			/* dv indicates 'data valid' (e.g., the tablet is in sync			 * and has delivered a "correct" report) We will ignore			 * all 'bad' reports...			 */			if (dv != 0) {				/* If we've not already sent a tool_button_?? code, do				 * so now. Then set FIRED_BIT so it won't be resent unless				 * the user forces FIRED_BIT off.				 */				if (TOOL_BUTTON_FIRED				    (aiptek->curSetting.toolMode) == 0) {					input_report_key(inputdev,							 TOOL_BUTTON(aiptek->curSetting.toolMode),							 1);					aiptek->curSetting.toolMode |= TOOL_BUTTON_FIRED_BIT;				}				if (p != 0) {					input_report_abs(inputdev, ABS_X, x);					input_report_abs(inputdev, ABS_Y, y);					input_report_abs(inputdev, ABS_PRESSURE, z);					input_report_key(inputdev, BTN_TOUCH, tip);					input_report_key(inputdev, BTN_STYLUS, bs);					input_report_key(inputdev, BTN_STYLUS2, pck);					if (aiptek->curSetting.xTilt !=					    AIPTEK_TILT_DISABLE) {						input_report_abs(inputdev,								 ABS_TILT_X,								 aiptek->curSetting.xTilt);					}					if (aiptek->curSetting.yTilt != AIPTEK_TILT_DISABLE) {						input_report_abs(inputdev,								 ABS_TILT_Y,								 aiptek->curSetting.yTilt);					}					/* Wheel support is in the form of a single-event					 * firing.					 */					if (aiptek->curSetting.wheel !=					    AIPTEK_WHEEL_DISABLE) {						input_report_abs(inputdev,								 ABS_WHEEL,								 aiptek->curSetting.wheel);						aiptek->curSetting.wheel = AIPTEK_WHEEL_DISABLE;					}				}				input_report_abs(inputdev, ABS_MISC, p | AIPTEK_REPORT_TOOL_STYLUS);				input_sync(inputdev);			}		}	}	/* Report 3's come from the mouse in absolute mode.	 */	else if (data[0] == 3) {		if (aiptek->curSetting.coordinateMode == AIPTEK_COORDINATE_RELATIVE_MODE) {			aiptek->diagnostic = AIPTEK_DIAGNOSTIC_SENDING_ABSOLUTE_IN_RELATIVE;		} else if (!AIPTEK_POINTER_ALLOW_MOUSE_MODE			(aiptek->curSetting.pointerMode)) {			aiptek->diagnostic = AIPTEK_DIAGNOSTIC_TOOL_DISALLOWED;		} else {			input_regs(inputdev, regs);			x = le16_to_cpu(get_unaligned((__le16 *) (data + 1)));			y = le16_to_cpu(get_unaligned((__le16 *) (data + 3)));			jitterable = data[5] & 0x1c;			p = (data[5] & 0x01) != 0 ? 1 : 0;			dv = (data[5] & 0x02) != 0 ? 1 : 0;			left = (data[5] & aiptek->curSetting.mouseButtonLeft) != 0 ? 1 : 0;			right = (data[5] & aiptek->curSetting.mouseButtonRight) != 0 ? 1 : 0;			middle = (data[5] & aiptek->curSetting.mouseButtonMiddle) != 0 ? 1 : 0;			if (dv != 0) {				/* If we've not already sent a tool_button_?? code, do				 * so now. Then set FIRED_BIT so it won't be resent unless				 * the user forces FIRED_BIT off.				 */				if (TOOL_BUTTON_FIRED				    (aiptek->curSetting.toolMode) == 0) {					input_report_key(inputdev,							 TOOL_BUTTON(aiptek->curSetting.toolMode),							 1);					aiptek->curSetting.toolMode |= TOOL_BUTTON_FIRED_BIT;				}				if (p != 0) {					input_report_abs(inputdev, ABS_X, x);					input_report_abs(inputdev, ABS_Y, y);					input_report_key(inputdev, BTN_LEFT, left);					input_report_key(inputdev, BTN_MIDDLE, middle);					input_report_key(inputdev, BTN_RIGHT, right);					/* Wheel support is in the form of a single-event					 * firing.					 */					if (aiptek->curSetting.wheel != AIPTEK_WHEEL_DISABLE) {						input_report_abs(inputdev,								 ABS_WHEEL,								 aiptek->curSetting.wheel);						aiptek->curSetting.wheel = AIPTEK_WHEEL_DISABLE;					}				}				input_report_rel(inputdev, REL_MISC, p | AIPTEK_REPORT_TOOL_MOUSE);				input_sync(inputdev);			}		}	}	/* Report 4s come from the macro keys when pressed by stylus	 */	else if (data[0] == 4) {		jitterable = data[1] & 0x18;		p = (data[1] & 0x01) != 0 ? 1 : 0;		dv = (data[1] & 0x02) != 0 ? 1 : 0;		tip = (data[1] & 0x04) != 0 ? 1 : 0;		bs = (data[1] & aiptek->curSetting.stylusButtonLower) != 0 ? 1 : 0;		pck = (data[1] & aiptek->curSetting.stylusButtonUpper) != 0 ? 1 : 0;		macro = data[3];		z = le16_to_cpu(get_unaligned((__le16 *) (data + 4)));		if (dv != 0) {			input_regs(inputdev, regs);			/* If we've not already sent a tool_button_?? code, do			 * so now. Then set FIRED_BIT so it won't be resent unless			 * the user forces FIRED_BIT off.			 */			if (TOOL_BUTTON_FIRED(aiptek->curSetting.toolMode) == 0) {				input_report_key(inputdev,						 TOOL_BUTTON(aiptek->curSetting.toolMode),						 1);				aiptek->curSetting.toolMode |= TOOL_BUTTON_FIRED_BIT;			}			if (p != 0) {				input_report_key(inputdev, BTN_TOUCH, tip);				input_report_key(inputdev, BTN_STYLUS, bs);				input_report_key(inputdev, BTN_STYLUS2, pck);				input_report_abs(inputdev, ABS_PRESSURE, z);			}			/* For safety, we're sending key 'break' codes for the			 * neighboring macro keys.			 */			if (macro > 0) {				input_report_key(inputdev,						 macroKeyEvents[macro - 1], 0);			}			if (macro < 25) {				input_report_key(inputdev,						 macroKeyEvents[macro + 1], 0);			}			input_report_key(inputdev, macroKeyEvents[macro], p);			input_report_abs(inputdev, ABS_MISC,					 p | AIPTEK_REPORT_TOOL_STYLUS);			input_sync(inputdev);		}	}	/* Report 5s come from the macro keys when pressed by mouse	 */	else if (data[0] == 5) {		jitterable = data[1] & 0x1c;		p = (data[1] & 0x01) != 0 ? 1 : 0;		dv = (data[1] & 0x02) != 0 ? 1 : 0;		left = (data[1]& aiptek->curSetting.mouseButtonLeft) != 0 ? 1 : 0;		right = (data[1] & aiptek->curSetting.mouseButtonRight) != 0 ? 1 : 0;		middle = (data[1] & aiptek->curSetting.mouseButtonMiddle) != 0 ? 1 : 0;		macro = data[3];		if (dv != 0) {			input_regs(inputdev, regs);			/* If we've not already sent a tool_button_?? code, do			 * so now. Then set FIRED_BIT so it won't be resent unless			 * the user forces FIRED_BIT off.			 */			if (TOOL_BUTTON_FIRED(aiptek->curSetting.toolMode) == 0) {				input_report_key(inputdev,						 TOOL_BUTTON(aiptek->curSetting.toolMode),						 1);				aiptek->curSetting.toolMode |= TOOL_BUTTON_FIRED_BIT;			}			if (p != 0) {				input_report_key(inputdev, BTN_LEFT, left);				input_report_key(inputdev, BTN_MIDDLE, middle);				input_report_key(inputdev, BTN_RIGHT, right);			}			/* For safety, we're sending key 'break' codes for the			 * neighboring macro keys.			 */			if (macro > 0) {				input_report_key(inputdev,						 macroKeyEvents[macro - 1], 0);			}			if (macro < 25) {				input_report_key(inputdev,						 macroKeyEvents[macro + 1], 0);			}			input_report_key(inputdev, macroKeyEvents[macro], 1);			input_report_rel(inputdev, ABS_MISC,					 p | AIPTEK_REPORT_TOOL_MOUSE);			input_sync(inputdev);		}	}	/* We have no idea which tool can generate a report 6. Theoretically,	 * neither need to, having been given reports 4 & 5 for such use.	 * However, report 6 is the 'official-looking' report for macroKeys;	 * reports 4 & 5 supposively are used to support unnamed, unknown	 * hat switches (which just so happen to be the macroKeys.)	 */	else if (data[0] == 6) {		macro = le16_to_cpu(get_unaligned((__le16 *) (data + 1)));		input_regs(inputdev, regs);		if (macro > 0) {			input_report_key(inputdev, macroKeyEvents[macro - 1],					 0);		}		if (macro < 25) {			input_report_key(inputdev, macroKeyEvents[macro + 1],					 0);		}		/* If we've not already sent a tool_button_?? code, do		 * so now. Then set FIRED_BIT so it won't be resent unless		 * the user forces FIRED_BIT off.		 */		if (TOOL_BUTTON_FIRED(aiptek->curSetting.toolMode) == 0) {			input_report_key(inputdev,					 TOOL_BUTTON(aiptek->curSetting.						     toolMode), 1);			aiptek->curSetting.toolMode |= TOOL_BUTTON_FIRED_BIT;		}		input_report_key(inputdev, macroKeyEvents[macro], 1);		input_report_abs(inputdev, ABS_MISC,				 1 | AIPTEK_REPORT_TOOL_UNKNOWN);		input_sync(inputdev);	} else {		dbg("Unknown report %d", data[0]);	}	/* Jitter may occur when the user presses a button on the stlyus	 * or the mouse. What we do to prevent that is wait 'x' milliseconds	 * following a 'jitterable' event, which should give the hand some time	 * stabilize itself.	 *	 * We just introduced aiptek->previousJitterable to carry forth the	 * notion that jitter occurs when the button state changes from on to off:	 * a person drawing, holding a button down is not subject to jittering.	 * With that in mind, changing from upper button depressed to lower button	 * WILL transition through a jitter delay.	 */	if (aiptek->previousJitterable != jitterable &&	    aiptek->curSetting.jitterDelay != 0 && aiptek->inDelay != 1) {		aiptek->endDelay = jiffies +		    ((aiptek->curSetting.jitterDelay * HZ) / 1000);		aiptek->inDelay = 1;	}	aiptek->previousJitterable = jitterable;exit:	retval = usb_submit_urb(urb, GFP_ATOMIC);	if (retval != 0) {		err("%s - usb_submit_urb failed with result %d",		    __FUNCTION__, retval);	}}/*********************************************************************** * These are the USB id's known so far. We do not identify them to * specific Aiptek model numbers, because there has been overlaps, * use, and reuse of id's in existing models. Certain models have * been known to use more than one ID, indicative perhaps of * manufacturing revisions. In any event, we consider these  * IDs to not be model-specific nor unique. */struct usb_device_id aiptek_ids[] = {	{USB_DEVICE(USB_VENDOR_ID_AIPTEK, 0x01)},	{USB_DEVICE(USB_VENDOR_ID_AIPTEK, 0x10)},	{USB_DEVICE(USB_VENDOR_ID_AIPTEK, 0x20)},	{USB_DEVICE(USB_VENDOR_ID_AIPTEK, 0x21)},	{USB_DEVICE(USB_VENDOR_ID_AIPTEK, 0x22)},	{USB_DEVICE(USB_VENDOR_ID_AIPTEK, 0x23)},	{USB_DEVICE(USB_VENDOR_ID_AIPTEK, 0x24)},	{}};MODULE_DEVICE_TABLE(usb, aiptek_ids);/*********************************************************************** * Open an instance of the tablet driver. */static int aiptek_open(struct input_dev *inputdev){	struct aiptek *aiptek = inputdev->private;	if (aiptek->openCount++ > 0) {		return 0;	}	aiptek->urb->dev = aiptek->usbdev;	if (usb_submit_urb(aiptek->urb, GFP_KERNEL) != 0) {		aiptek->openCount--;		return -EIO;	}	return 0;}/*********************************************************************** * Close an instance of the tablet driver. */static void aiptek_close(struct input_dev *inputdev){	struct aiptek *aiptek = inputdev->private;	if (--aiptek->openCount == 0) {		usb_kill_urb(aiptek->urb);	}}/*********************************************************************** * aiptek_set_report and aiptek_get_report() are borrowed from Linux 2.4.x,  * where they were known as usb_set_report and usb_get_report.

⌨️ 快捷键说明

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