diff options
Diffstat (limited to 'drivers/input/touchscreen/usbtouchscreen.c')
| -rw-r--r-- | drivers/input/touchscreen/usbtouchscreen.c | 104 | 
1 files changed, 100 insertions, 4 deletions
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c index 68ece5801a5..09a5e7341bd 100644 --- a/drivers/input/touchscreen/usbtouchscreen.c +++ b/drivers/input/touchscreen/usbtouchscreen.c @@ -14,6 +14,7 @@   *  - General Touch   *  - GoTop Super_Q2/GogoPen/PenPower tablets   *  - JASTEC USB touch controller/DigiTech DTR-02U + *  - Zytronic capacitive touchscreen   *   * Copyright (C) 2004-2007 by Daniel Ritz <daniel.ritz@gmx.ch>   * Copyright (C) by Todd E. Johnson (mtouchusb.c) @@ -73,6 +74,15 @@ struct usbtouch_device_info {  	int min_press, max_press;  	int rept_size; +	/* +	 * Always service the USB devices irq not just when the input device is +	 * open. This is useful when devices have a watchdog which prevents us +	 * from periodically polling the device. Leave this unset unless your +	 * touchscreen device requires it, as it does consume more of the USB +	 * bandwidth. +	 */ +	bool irq_always; +  	void (*process_pkt) (struct usbtouch_usb *usbtouch, unsigned char *pkt, int len);  	/* @@ -121,6 +131,8 @@ enum {  	DEVTYPE_GOTOP,  	DEVTYPE_JASTEC,  	DEVTYPE_E2I, +	DEVTYPE_ZYTRONIC, +	DEVTYPE_TC5UH,  };  #define USB_DEVICE_HID_CLASS(vend, prod) \ @@ -201,6 +213,15 @@ static struct usb_device_id usbtouch_devices[] = {  #ifdef CONFIG_TOUCHSCREEN_USB_E2I  	{USB_DEVICE(0x1ac7, 0x0001), .driver_info = DEVTYPE_E2I},  #endif + +#ifdef CONFIG_TOUCHSCREEN_USB_ZYTRONIC +	{USB_DEVICE(0x14c8, 0x0003), .driver_info = DEVTYPE_ZYTRONIC}, +#endif + +#ifdef CONFIG_TOUCHSCREEN_USB_ETT_TC5UH +	{USB_DEVICE(0x0664, 0x0309), .driver_info = DEVTYPE_TC5UH}, +#endif +  	{}  }; @@ -538,6 +559,19 @@ static int irtouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt)  }  #endif +/***************************************************************************** + * ET&T TC5UH part + */ +#ifdef CONFIG_TOUCHSCREEN_USB_ETT_TC5UH +static int tc5uh_read_data(struct usbtouch_usb *dev, unsigned char *pkt) +{ +	dev->x = ((pkt[2] & 0x0F) << 8) | pkt[1]; +	dev->y = ((pkt[4] & 0x0F) << 8) | pkt[3]; +	dev->touch = pkt[0] & 0x01; + +	return 1; +} +#endif  /*****************************************************************************   * IdealTEK URTC1000 Part @@ -621,6 +655,39 @@ static int jastec_read_data(struct usbtouch_usb *dev, unsigned char *pkt)  }  #endif +/***************************************************************************** + * Zytronic Part + */ +#ifdef CONFIG_TOUCHSCREEN_USB_ZYTRONIC +static int zytronic_read_data(struct usbtouch_usb *dev, unsigned char *pkt) +{ +	switch (pkt[0]) { +	case 0x3A: /* command response */ +		dbg("%s: Command response %d", __func__, pkt[1]); +		break; + +	case 0xC0: /* down */ +		dev->x = (pkt[1] & 0x7f) | ((pkt[2] & 0x07) << 7); +		dev->y = (pkt[3] & 0x7f) | ((pkt[4] & 0x07) << 7); +		dev->touch = 1; +		dbg("%s: down %d,%d", __func__, dev->x, dev->y); +		return 1; + +	case 0x80: /* up */ +		dev->x = (pkt[1] & 0x7f) | ((pkt[2] & 0x07) << 7); +		dev->y = (pkt[3] & 0x7f) | ((pkt[4] & 0x07) << 7); +		dev->touch = 0; +		dbg("%s: up %d,%d", __func__, dev->x, dev->y); +		return 1; + +	default: +		dbg("%s: Unknown return %d", __func__, pkt[0]); +		break; +	} + +	return 0; +} +#endif  /*****************************************************************************   * the different device descriptors @@ -783,6 +850,29 @@ static struct usbtouch_device_info usbtouch_dev_info[] = {  		.read_data	= e2i_read_data,  	},  #endif + +#ifdef CONFIG_TOUCHSCREEN_USB_ZYTRONIC +	[DEVTYPE_ZYTRONIC] = { +		.min_xc		= 0x0, +		.max_xc		= 0x03ff, +		.min_yc		= 0x0, +		.max_yc		= 0x03ff, +		.rept_size	= 5, +		.read_data	= zytronic_read_data, +		.irq_always     = true, +	}, +#endif + +#ifdef CONFIG_TOUCHSCREEN_USB_ETT_TC5UH +	[DEVTYPE_TC5UH] = { +		.min_xc		= 0x0, +		.max_xc		= 0x0fff, +		.min_yc		= 0x0, +		.max_yc		= 0x0fff, +		.rept_size	= 5, +		.read_data	= tc5uh_read_data, +	}, +#endif  }; @@ -933,8 +1023,10 @@ static int usbtouch_open(struct input_dev *input)  	usbtouch->irq->dev = usbtouch->udev; -	if (usb_submit_urb(usbtouch->irq, GFP_KERNEL)) -		return -EIO; +	if (!usbtouch->type->irq_always) { +		if (usb_submit_urb(usbtouch->irq, GFP_KERNEL)) +		  return -EIO; +	}  	return 0;  } @@ -943,7 +1035,8 @@ static void usbtouch_close(struct input_dev *input)  {  	struct usbtouch_usb *usbtouch = input_get_drvdata(input); -	usb_kill_urb(usbtouch->irq); +	if (!usbtouch->type->irq_always) +		usb_kill_urb(usbtouch->irq);  } @@ -1066,6 +1159,9 @@ static int usbtouch_probe(struct usb_interface *intf,  	usb_set_intfdata(intf, usbtouch); +	if (usbtouch->type->irq_always) +		usb_submit_urb(usbtouch->irq, GFP_KERNEL); +  	return 0;  out_free_buffers: @@ -1087,7 +1183,7 @@ static void usbtouch_disconnect(struct usb_interface *intf)  	dbg("%s - usbtouch is initialized, cleaning up", __func__);  	usb_set_intfdata(intf, NULL); -	usb_kill_urb(usbtouch->irq); +	/* this will stop IO via close */  	input_unregister_device(usbtouch->input);  	usb_free_urb(usbtouch->irq);  	usbtouch_free_buffers(interface_to_usbdev(intf), usbtouch);  |