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

📄 aiptek.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		*/		if (aiptek->previousToolMode !=		    aiptek->curSetting.toolMode) {		        input_report_key(inputdev,					 aiptek->previousToolMode, 0);			input_report_key(inputdev,					 aiptek->curSetting.toolMode,					 1);			aiptek->previousToolMode =				aiptek->curSetting.toolMode;		}		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. */static const 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 = input_get_drvdata(inputdev);	aiptek->urb->dev = aiptek->usbdev;	if (usb_submit_urb(aiptek->urb, GFP_KERNEL) != 0)		return -EIO;	return 0;}/*********************************************************************** * Close an instance of the tablet driver. */static void aiptek_close(struct input_dev *inputdev){	struct aiptek *aiptek = input_get_drvdata(inputdev);	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. */static intaiptek_set_report(struct aiptek *aiptek,		  unsigned char report_type,		  unsigned char report_id, void *buffer, int size){	return usb_control_msg(aiptek->usbdev,			       usb_sndctrlpipe(aiptek->usbdev, 0),			       USB_REQ_SET_REPORT,			       USB_TYPE_CLASS | USB_RECIP_INTERFACE |			       USB_DIR_OUT, (report_type << 8) + report_id,			       aiptek->ifnum, buffer, size, 5000);}static intaiptek_get_report(struct aiptek *aiptek,		  unsigned char report_type,		  unsigned char report_id, void *buffer, int size){	return usb_control_msg(aiptek->usbdev,			       usb_rcvctrlpipe(aiptek->usbdev, 0),			       USB_REQ_GET_REPORT,			       USB_TYPE_CLASS | USB_RECIP_INTERFACE |			       USB_DIR_IN, (report_type << 8) + report_id,			       aiptek->ifnum, buffer, size, 5000);}/*********************************************************************** * Send a command to the tablet. */static intaiptek_command(struct aiptek *aiptek, unsigned char command, unsigned char data){	const int sizeof_buf = 3 * sizeof(u8);	int ret;	u8 *buf;	buf = kmalloc(sizeof_buf, GFP_KERNEL);	if (!buf)		return -ENOMEM;	buf[0] = 2;	buf[1] = command;	buf[2] = data;	if ((ret =	     aiptek_set_report(aiptek, 3, 2, buf, sizeof_buf)) != sizeof_buf) {		dbg("aiptek_program: failed, tried to send: 0x%02x 0x%02x",		    command, data);	}	kfree(buf);	return ret < 0 ? ret : 0;}/*********************************************************************** * Retrieve information from the tablet. Querying info is defined as first * sending the {command,data} sequence as a command, followed by a wait * (aka, "programmaticDelay") and then a "read" request. */static intaiptek_query(struct aiptek *aiptek, unsigned char command, unsigned char data){	const int sizeof_buf = 3 * sizeof(u8);	int ret;	u8 *buf;	buf = kmalloc(sizeof_buf, GFP_KERNEL);	if (!buf)		return -ENOMEM;	buf[0] = 2;	buf[1] = command;	buf[2] = data;	if (aiptek_command(aiptek, command, data) != 0) {		kfree(buf);		return -EIO;	}	msleep(aiptek->curSetting.programmableDelay);	if ((ret =	     aiptek_get_report(aiptek, 3, 2, buf, sizeof_buf)) != sizeof_buf) {		dbg("aiptek_query failed: returned 0x%02x 0x%02x 0x%02x",		    buf[0], buf[1], buf[2]);		ret = -EIO;	} else {		ret = le16_to_cpu(get_unaligned((__le16 *) (buf + 1)));	}	kfree(buf);	return ret;}/*********************************************************************** * Program the tablet into either absolute or relative mode. * We also get information about the tablet's size. */static int aiptek_program_tablet(struct aiptek *aiptek){	int ret;	/* Execute Resolution500LPI */	if ((ret = aiptek_command(aiptek, 0x18, 0x04)) < 0)		return ret;	/* Query getModelCode */	if ((ret = aiptek_query(aiptek, 0x02, 0x00)) < 0)		return ret;	aiptek->features.modelCode = ret & 0xff;	/* Query getODMCode */	if ((ret = aiptek_query(aiptek, 0x03, 0x00)) < 0)		return ret;	aiptek->features.odmCode = ret;	/* Query getFirmwareCode */	if ((ret = aiptek_query(aiptek, 0x04, 0x00)) < 0)		return ret;	aiptek->features.firmwareCode = ret;	/* Query getXextension */	if ((ret = aiptek_query(aiptek, 0x01, 0x00)) < 0)		return ret;	aiptek->inputdev->absmin[ABS_X] = 0;	aiptek->inputdev->absmax[ABS_X] = ret - 1;	/* Query getYextension */	if ((ret = aiptek_query(aiptek, 0x01, 0x01)) < 0)		return ret;	aiptek->inputdev->absmin[ABS_Y] = 0;	aiptek->inputdev->absmax[ABS_Y] = ret - 1;	/* Query getPressureLevels */	if ((ret = aiptek_query(aiptek, 0x08, 0x00)) < 0)		return ret;	aiptek->inputdev->absmin[ABS_PRESSURE] = 0;	aiptek->inputdev->absmax[ABS_PRESSURE] = ret - 1;	/* Depending on whether we are in absolute or relative mode, we will	 * do a switchToTablet(absolute) or switchToMouse(relative) command.	 */	if (aiptek->curSetting.coordinateMode ==	    AIPTEK_COORDINATE_ABSOLUTE_MODE) {		/* Execute switchToTablet */		if ((ret = aiptek_command(aiptek, 0x10, 0x01)) < 0) {			return ret;		}	} else {		/* Execute switchToMouse */		if ((ret = aiptek_command(aiptek, 0x10, 0x00)) < 0) {			return ret;		}	}	/* Enable the macro keys */	if ((ret = aiptek_command(aiptek, 0x11, 0x02)) < 0)		return ret;#if 0	/* Execute FilterOn */	if ((ret = aiptek_command(aiptek, 0x17, 0x00)) < 0)		return ret;#endif	/* Execute AutoGainOn */	if ((ret = aiptek_command(aiptek, 0x12, 0xff)) < 0)		return ret;	/* Reset the eventCount, so we track events from last (re)programming	 */	aiptek->diagnostic = AIPTEK_DIAGNOSTIC_NA;	aiptek->eventCount = 0;	return 0;}/*********************************************************************** * Sysfs functions. Sysfs prefers that individually-tunable parameters * exist in their separate pseudo-files. Summary data that is immutable * may exist in a singular file so long as you don't define a writeable * interface. *//*********************************************************************** * support the 'size' file -- display support */static ssize_t show_tabletSize(struct device *dev, struct device_attribute *attr, char *buf){	struct aiptek *aiptek = dev_get_drvdata(dev);	return snprintf(buf, PAGE_SIZE, "%dx%d\n",			aiptek->inputdev->absmax[ABS_X] + 1,			aiptek->inputdev->absmax[ABS_Y] + 1);}/* These structs define the sysfs files, param #1 is the name of the * file, param 2 is the file permissions, param 3 & 4 are to the * output generator and input parser routines. Absence of a routine is * permitted -- it only means can't either 'cat' the file, or send data * to it. */static DEVICE_ATTR(size, S_IRUGO, show_tabletSize, NULL);/*********************************************************************** * support routines for the 'pointer_mode' file. Note that this file * both displays current setting and allows reprogramming. */static struct aiptek_map pointer_mode_map[] = {	{ "stylus",	AIPTEK_POINTER_ONLY_STYLUS_MODE },	{ "mouse",	AIPTEK_POINTER_ONLY_MOUSE_MODE },	{ "either",	AIPTEK_POINTER_EITHER_MODE },	{ NULL,		AIPTEK_INVALID_VALUE }};static ssize_t show_tabletPointerMode(struct device *dev, struct device_attribute *attr, char *buf){	struct aiptek *aiptek = dev_get_drvdata(dev);	return snprintf(buf, PAGE_SIZE, "%s\n",			map_val_to_str(pointer_mode_map,					aiptek->curSetting.pointerMode));}static ssize_tstore_tabletPointerMode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){	struct aiptek *aiptek = dev_get_drvdata(dev);	int new_mode = map_str_to_val(pointer_mode_map, buf, count);	if (new_mode == AIPTEK_INVALID_VALUE)		return -EINVAL;	aiptek->newSetting.pointerMode = new_mode;	return count;}static DEVICE_ATTR(pointer_mode,		   S_IRUGO | S_IWUGO,		   show_tabletPointerMode, store_tabletPointerMode);/*********************************************************************** * support routines for the 'coordinate_mode' file. Note that this file * both displays current setting and allows reprogramming. */static struct aiptek_map coordinate_mode_map[] = {	{ "absolute",	AIPTEK_COORDINATE_ABSOLUTE_MODE },	{ "relative",	AIPTEK_COORDINATE_RELATIVE_MODE },	{ NULL,		AIPTEK_INVALID_VALUE }};static ssize_t show_tabletCoordinateMode(struct device *dev, struct device_attribute *attr, char *buf){	struct aiptek *aiptek = dev_get_drvdata(dev);	return snprintf(buf, PAGE_SIZE, "%s\n",			map_val_to_str(coordinate_mode_map,					aiptek->curSetting.coordinateMode));}static ssize_tstore_tabletCoordinateMode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){	struct aiptek *aiptek = dev_get_drvdata(dev);	int new_mode = map_str_to_val(coordinate_mode_map, buf, count);	if (new_mode == AIPTEK_INVALID_VALUE)		return -EINVAL;	aiptek->newSetting.coordinateMode = new_mode;	return count;}static DEVICE_ATTR(coordinate_mode,		   S_IRUGO | S_IWUGO,		   show_tabletCoordinateMode, store_tabletCoordinateMode);/*********************************************************************** * support routines for the 'tool_mode' file. Note that this file * both displays current setting and allows reprogramming. */static struct aiptek_map tool_mode_map[] = {	{ "mouse",	AIPTEK_TOOL_BUTTON_MOUSE_MODE },	{ "eraser",	AIPTEK_TOOL_BUTTON_ERASER_MODE },	{ "pencil",	AIPTEK_TOOL_BUTTON_PENCIL_MODE },	{ "pen",	AIPTEK_TOOL_BUTTON_PEN_MODE },	{ "brush",	AIPTEK_TOOL_BUTTON_BRUSH_MODE },	{ "airbrush",	AIPTEK_TOOL_BUTTON_AIRBRUSH_MODE },	{ "lens",	AIPTEK_TOOL_BUTTON_LENS_MODE },	{ NULL,		AIPTEK_INVALID_VALUE }};

⌨️ 快捷键说明

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