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

📄 aiptek.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
	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);	if (aiptek == NULL)		return 0;	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 'product_id' file */static ssize_t show_tabletProductId(struct device *dev, struct device_attribute *attr, char *buf){	struct aiptek *aiptek = dev_get_drvdata(dev);	if (aiptek == NULL)		return 0;	return snprintf(buf, PAGE_SIZE, "0x%04x\n",			aiptek->inputdev->id.product);}static DEVICE_ATTR(product_id, S_IRUGO, show_tabletProductId, NULL);/*********************************************************************** * support routines for the 'vendor_id' file */static ssize_t show_tabletVendorId(struct device *dev, struct device_attribute *attr, char *buf){	struct aiptek *aiptek = dev_get_drvdata(dev);	if (aiptek == NULL)		return 0;	return snprintf(buf, PAGE_SIZE, "0x%04x\n", aiptek->inputdev->id.vendor);}static DEVICE_ATTR(vendor_id, S_IRUGO, show_tabletVendorId, NULL);/*********************************************************************** * support routines for the 'vendor' file */static ssize_t show_tabletManufacturer(struct device *dev, struct device_attribute *attr, char *buf){	struct aiptek *aiptek = dev_get_drvdata(dev);	int retval;	if (aiptek == NULL)		return 0;	retval = snprintf(buf, PAGE_SIZE, "%s\n", aiptek->usbdev->manufacturer);	return retval;}static DEVICE_ATTR(vendor, S_IRUGO, show_tabletManufacturer, NULL);/*********************************************************************** * support routines for the 'product' file */static ssize_t show_tabletProduct(struct device *dev, struct device_attribute *attr, char *buf){	struct aiptek *aiptek = dev_get_drvdata(dev);	int retval;	if (aiptek == NULL)		return 0;	retval = snprintf(buf, PAGE_SIZE, "%s\n", aiptek->usbdev->product);	return retval;}static DEVICE_ATTR(product, S_IRUGO, show_tabletProduct, NULL);/*********************************************************************** * support routines for the 'pointer_mode' file. Note that this file * both displays current setting and allows reprogramming. */static ssize_t show_tabletPointerMode(struct device *dev, struct device_attribute *attr, char *buf){	struct aiptek *aiptek = dev_get_drvdata(dev);	char *s;	if (aiptek == NULL)		return 0;	switch (aiptek->curSetting.pointerMode) {	case AIPTEK_POINTER_ONLY_STYLUS_MODE:		s = "stylus";		break;	case AIPTEK_POINTER_ONLY_MOUSE_MODE:		s = "mouse";		break;	case AIPTEK_POINTER_EITHER_MODE:		s = "either";		break;	default:		s = "unknown";		break;	}	return snprintf(buf, PAGE_SIZE, "%s\n", s);}static ssize_tstore_tabletPointerMode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){	struct aiptek *aiptek = dev_get_drvdata(dev);	if (aiptek == NULL)		return 0;	if (strcmp(buf, "stylus") == 0) {		aiptek->newSetting.pointerMode =		    AIPTEK_POINTER_ONLY_STYLUS_MODE;	} else if (strcmp(buf, "mouse") == 0) {		aiptek->newSetting.pointerMode = AIPTEK_POINTER_ONLY_MOUSE_MODE;	} else if (strcmp(buf, "either") == 0) {		aiptek->newSetting.pointerMode = AIPTEK_POINTER_EITHER_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 ssize_t show_tabletCoordinateMode(struct device *dev, struct device_attribute *attr, char *buf){	struct aiptek *aiptek = dev_get_drvdata(dev);	char *s;	if (aiptek == NULL)		return 0;	switch (aiptek->curSetting.coordinateMode) {	case AIPTEK_COORDINATE_ABSOLUTE_MODE:		s = "absolute";		break;	case AIPTEK_COORDINATE_RELATIVE_MODE:		s = "relative";		break;	default:		s = "unknown";		break;	}	return snprintf(buf, PAGE_SIZE, "%s\n", s);}static ssize_tstore_tabletCoordinateMode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){	struct aiptek *aiptek = dev_get_drvdata(dev);	if (aiptek == NULL)		return 0;	if (strcmp(buf, "absolute") == 0) {		aiptek->newSetting.pointerMode =		    AIPTEK_COORDINATE_ABSOLUTE_MODE;	} else if (strcmp(buf, "relative") == 0) {		aiptek->newSetting.pointerMode =		    AIPTEK_COORDINATE_RELATIVE_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 ssize_t show_tabletToolMode(struct device *dev, struct device_attribute *attr, char *buf){	struct aiptek *aiptek = dev_get_drvdata(dev);	char *s;	if (aiptek == NULL)		return 0;	switch (TOOL_BUTTON(aiptek->curSetting.toolMode)) {	case AIPTEK_TOOL_BUTTON_MOUSE_MODE:		s = "mouse";		break;	case AIPTEK_TOOL_BUTTON_ERASER_MODE:		s = "eraser";		break;	case AIPTEK_TOOL_BUTTON_PENCIL_MODE:		s = "pencil";		break;	case AIPTEK_TOOL_BUTTON_PEN_MODE:		s = "pen";		break;	case AIPTEK_TOOL_BUTTON_BRUSH_MODE:		s = "brush";		break;	case AIPTEK_TOOL_BUTTON_AIRBRUSH_MODE:		s = "airbrush";		break;	case AIPTEK_TOOL_BUTTON_LENS_MODE:

⌨️ 快捷键说明

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