aiptek.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:8k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  *  Native support for the Aiptek 8000U
  3.  *
  4.  *  Copyright (c) 2001 Chris Atenasio <chris@crud.net>
  5.  *
  6.  *  based on wacom.c by
  7.  *     Vojtech Pavlik      <vojtech@suse.cz>
  8.  *     Andreas Bach Aaen   <abach@stofanet.dk>
  9.  *     Clifford Wolf       <clifford@clifford.at>
  10.  *     Sam Mosel           <sam.mosel@computer.org>
  11.  *     James E. Blair      <corvus@gnu.org>
  12.  *     Daniel Egger        <egger@suse.de>
  13.  *
  14.  *
  15.  *  Many thanks to Oliver Kuechemann for his support.
  16.  *
  17.  *  ChangeLog:
  18.  *      v0.1 - Initial release
  19.  *      v0.2 - Hack to get around fake event 28's.
  20.  *      v0.3 - Make URB dynamic (Bryan W. Headley, Jun-8-2002)
  21.  */
  22. /*
  23.  * This program is free software; you can redistribute it and/or modify
  24.  * it under the terms of the GNU General Public License as published by
  25.  * the Free Software Foundation; either version 2 of the License, or
  26.  * (at your option) any later version.
  27.  *
  28.  * This program is distributed in the hope that it will be useful,
  29.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  30.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  31.  * GNU General Public License for more details.
  32.  *
  33.  * You should have received a copy of the GNU General Public License
  34.  * along with this program; if not, write to the Free Software
  35.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  36.  */
  37. #include <linux/kernel.h>
  38. #include <linux/slab.h>
  39. #include <linux/input.h>
  40. #include <linux/module.h>
  41. #include <linux/init.h>
  42. #include <linux/usb.h>
  43. /*
  44.  * Version Information
  45.  */
  46. #define DRIVER_VERSION "v0.3"
  47. #define DRIVER_AUTHOR "Chris Atenasio <chris@crud.net>"
  48. #define DRIVER_DESC "USB Aiptek 6000U/8000U tablet driver (Linux 2.4.x)"
  49. MODULE_AUTHOR(DRIVER_AUTHOR);
  50. MODULE_DESCRIPTION(DRIVER_DESC);
  51. MODULE_LICENSE("GPL");
  52. /*
  53.  * Aiptek status packet:
  54.  *
  55.  *        bit7  bit6  bit5  bit4  bit3  bit2  bit1  bit0
  56.  * byte0   0     0     0     0     0     0     1     0
  57.  * byte1  X7    X6    X5    X4    X3    X2    X1    X0
  58.  * byte2  X15   X14   X13   X12   X11   X10   X9    X8
  59.  * byte3  Y7    Y6    Y5    Y4    Y3    Y2    Y1    Y0
  60.  * byte4  Y15   Y14   Y13   Y12   Y11   Y10   Y9    Y8
  61.  * byte5   *     *     *    BS2   BS1   Tip   DV    IR
  62.  * byte6  P7    P6    P5    P4    P3    P2    P1    P0
  63.  * byte7  P15   P14   P13   P12   P11   P10   P9    P8
  64.  *
  65.  * IR: In Range = Proximity on
  66.  * DV = Data Valid
  67.  *
  68.  * 
  69.  * Command Summary:
  70.  *
  71.  * Command/Data    Description     Return Bytes    Return Value
  72.  * 0x10/0x00       SwitchToMouse       0
  73.  * 0x10/0x01       SwitchToTablet      0
  74.  * 0x18/0x04       Resolution500LPI    0
  75.  * 0x17/0x00       FilterOn            0
  76.  * 0x12/0xFF       AutoGainOn          0
  77.  * 0x01/0x00       GetXExtension       2           MaxX
  78.  * 0x01/0x01       GetYExtension       2           MaxY
  79.  * 0x02/0x00       GetModelCode        2           ModelCode = LOBYTE
  80.  * 0x03/0x00       GetODMCode          2           ODMCode
  81.  * 0x08/0x00       GetPressureLevels   2           =512
  82.  * 0x04/0x00       GetFirmwareVersion  2           Firmware Version
  83.  *
  84.  *
  85.  * To initialize the tablet:
  86.  *
  87.  * (1) Send command Resolution500LPI
  88.  * (2) Option Commands (GetXExtension, GetYExtension)
  89.  * (3) Send command SwitchToTablet
  90.  */
  91. #define USB_VENDOR_ID_AIPTEK   0x08ca
  92. struct aiptek_features {
  93. char *name;
  94. int pktlen;
  95. int x_max;
  96. int y_max;
  97. int pressure_min;
  98. int pressure_max;
  99. void (*irq) (struct urb * urb);
  100. unsigned long evbit;
  101. unsigned long absbit;
  102. unsigned long relbit;
  103. unsigned long btnbit;
  104. unsigned long digibit;
  105. };
  106. struct aiptek {
  107. signed char data[10];
  108. struct input_dev dev;
  109. struct usb_device *usbdev;
  110. struct urb *irq;
  111. struct aiptek_features *features;
  112. int tool;
  113. int open;
  114. };
  115. static void
  116. aiptek_irq(struct urb *urb)
  117. {
  118. struct aiptek *aiptek = urb->context;
  119. unsigned char *data = aiptek->data;
  120. struct input_dev *dev = &aiptek->dev;
  121. int x;
  122. int y;
  123. int pressure;
  124. int proximity;
  125. if (urb->status)
  126. return;
  127. if ((data[0] & 2) == 0) {
  128. dbg("received unknown report #%d", data[0]);
  129. }
  130. proximity = data[5] & 0x01;
  131. input_report_key(dev, BTN_TOOL_PEN, proximity);
  132. x = ((__u32) data[1]) | ((__u32) data[2] << 8);
  133. y = ((__u32) data[3]) | ((__u32) data[4] << 8);
  134. pressure = ((__u32) data[6]) | ((__u32) data[7] << 8);
  135. pressure -= aiptek->features->pressure_min;
  136. if (pressure < 0) {
  137. pressure = 0;
  138. }
  139. if (proximity) {
  140. input_report_abs(dev, ABS_X, x);
  141. input_report_abs(dev, ABS_Y, y);
  142. input_report_abs(dev, ABS_PRESSURE, pressure);
  143. input_report_key(dev, BTN_TOUCH, data[5] & 0x04);
  144. input_report_key(dev, BTN_STYLUS, data[5] & 0x08);
  145. input_report_key(dev, BTN_STYLUS2, data[5] & 0x10);
  146. }
  147. }
  148. struct aiptek_features aiptek_features[] = {
  149. {"Aiptek 6000U/8000U", 
  150.  8, 3000, 2250, 26, 511, aiptek_irq, 0, 0, 0, 0},
  151. {NULL, 0}
  152. };
  153. struct usb_device_id aiptek_ids[] = {
  154. {USB_DEVICE(USB_VENDOR_ID_AIPTEK, 0x20), driver_info:0},
  155. {}
  156. };
  157. MODULE_DEVICE_TABLE(usb, aiptek_ids);
  158. static int
  159. aiptek_open(struct input_dev *dev)
  160. {
  161. struct aiptek *aiptek = dev->private;
  162. if (aiptek->open++)
  163. return 0;
  164. aiptek->irq->dev = aiptek->usbdev;
  165. if (usb_submit_urb(aiptek->irq))
  166. return -EIO;
  167. return 0;
  168. }
  169. static void
  170. aiptek_close(struct input_dev *dev)
  171. {
  172. struct aiptek *aiptek = dev->private;
  173. if (!--aiptek->open)
  174. usb_unlink_urb(aiptek->irq);
  175. }
  176. static void
  177. aiptek_command(struct usb_device *dev, unsigned int ifnum,
  178.        unsigned char command, unsigned char data)
  179. {
  180. __u8 buf[3];
  181. buf[0] = 4;
  182. buf[1] = command;
  183. buf[2] = data;
  184. if (usb_set_report(dev, ifnum, 3, 2, buf, 3) != 3) {
  185. dbg("aiptek_command: 0x%x 0x%xn", command, data);
  186. }
  187. }
  188. static void*
  189. aiptek_probe(struct usb_device *dev, unsigned int ifnum,
  190.      const struct usb_device_id *id)
  191. {
  192. struct usb_endpoint_descriptor *endpoint;
  193. struct aiptek *aiptek;
  194. if (!(aiptek = kmalloc(sizeof (struct aiptek), GFP_KERNEL)))
  195. return NULL;
  196. memset(aiptek, 0, sizeof (struct aiptek));
  197. aiptek->irq = usb_alloc_urb(0);
  198. if (!aiptek->irq) {
  199. kfree(aiptek);
  200. return NULL;
  201. }
  202. // Resolution500LPI
  203. aiptek_command(dev, ifnum, 0x18, 0x04);
  204. // SwitchToTablet
  205. aiptek_command(dev, ifnum, 0x10, 0x01);
  206. aiptek->features = aiptek_features + id->driver_info;
  207. aiptek->dev.evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_MSC) |
  208.     aiptek->features->evbit;
  209. aiptek->dev.absbit[0] |= BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE) |
  210.     BIT(ABS_MISC) | aiptek->features->absbit;
  211. aiptek->dev.relbit[0] |= aiptek->features->relbit;
  212. aiptek->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) |
  213.     BIT(BTN_MIDDLE) | aiptek->features->btnbit;
  214. aiptek->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) |
  215.     BIT(BTN_TOOL_MOUSE) | BIT(BTN_TOUCH) |
  216.     BIT(BTN_STYLUS) | BIT(BTN_STYLUS2) | aiptek->features->digibit;
  217. aiptek->dev.mscbit[0] = BIT(MSC_SERIAL);
  218. aiptek->dev.absmax[ABS_X] = aiptek->features->x_max;
  219. aiptek->dev.absmax[ABS_Y] = aiptek->features->y_max;
  220. aiptek->dev.absmax[ABS_PRESSURE] = aiptek->features->pressure_max -
  221.     aiptek->features->pressure_min;
  222. aiptek->dev.absfuzz[ABS_X] = 0;
  223. aiptek->dev.absfuzz[ABS_Y] = 0;
  224. aiptek->dev.private = aiptek;
  225. aiptek->dev.open = aiptek_open;
  226. aiptek->dev.close = aiptek_close;
  227. aiptek->dev.name = aiptek->features->name;
  228. aiptek->dev.idbus = BUS_USB;
  229. aiptek->dev.idvendor = dev->descriptor.idVendor;
  230. aiptek->dev.idproduct = dev->descriptor.idProduct;
  231. aiptek->dev.idversion = dev->descriptor.bcdDevice;
  232. aiptek->usbdev = dev;
  233. endpoint = dev->config[0].interface[ifnum].altsetting[0].endpoint + 0;
  234. FILL_INT_URB(aiptek->irq,
  235.   dev,
  236.   usb_rcvintpipe(dev, endpoint->bEndpointAddress),
  237.          aiptek->data,
  238.   aiptek->features->pktlen,
  239.          aiptek->features->irq,
  240.   aiptek,
  241.   endpoint->bInterval);
  242. input_register_device(&aiptek->dev);
  243. printk(KERN_INFO "input%d: %s on usb%d:%d.%dn",
  244.        aiptek->dev.number, aiptek->features->name, dev->bus->busnum,
  245.        dev->devnum, ifnum);
  246. return aiptek;
  247. }
  248. static void
  249. aiptek_disconnect(struct usb_device *dev, void *ptr)
  250. {
  251. struct aiptek *aiptek = ptr;
  252. usb_unlink_urb(aiptek->irq);
  253. input_unregister_device(&aiptek->dev);
  254. usb_free_urb(aiptek->irq);
  255. kfree(aiptek);
  256. }
  257. static struct usb_driver aiptek_driver = {
  258. name:"aiptek",
  259. probe:aiptek_probe,
  260. disconnect:aiptek_disconnect,
  261. id_table:aiptek_ids,
  262. };
  263. static int __init
  264. aiptek_init(void)
  265. {
  266. usb_register(&aiptek_driver);
  267. info(DRIVER_VERSION " " DRIVER_AUTHOR);
  268. info(DRIVER_DESC);
  269. return 0;
  270. }
  271. static void __exit
  272. aiptek_exit(void)
  273. {
  274. usb_deregister(&aiptek_driver);
  275. }
  276. module_init(aiptek_init);
  277. module_exit(aiptek_exit);