11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Native support for the Aiptek HyperPen USB Tablets 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (4000U/5000U/6000U/8000U/12000U) 405f091ab4c8c1f12f8dd38ee789489904fea327dDmitry Torokhov * 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (c) 2001 Chris Atenasio <chris@crud.net> 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (c) 2002-2004 Bryan W. Headley <bwheadley@earthlink.net> 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * based on wacom.c by 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Vojtech Pavlik <vojtech@suse.cz> 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Andreas Bach Aaen <abach@stofanet.dk> 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Clifford Wolf <clifford@clifford.at> 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Sam Mosel <sam.mosel@computer.org> 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * James E. Blair <corvus@gnu.org> 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Daniel Egger <egger@suse.de> 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Many thanks to Oliver Kuechemann for his support. 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ChangeLog: 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * v0.1 - Initial release 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * v0.2 - Hack to get around fake event 28's. (Bryan W. Headley) 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * v0.3 - Make URB dynamic (Bryan W. Headley, Jun-8-2002) 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Released to Linux 2.4.19 and 2.5.x 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * v0.4 - Rewrote substantial portions of the code to deal with 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * corrected control sequences, timing, dynamic configuration, 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * support of 6000U - 12000U, procfs, and macro key support 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (Jan-1-2003 - Feb-5-2003, Bryan W. Headley) 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * v1.0 - Added support for diagnostic messages, count of messages 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * received from URB - Mar-8-2003, Bryan W. Headley 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * v1.1 - added support for tablet resolution, changed DV and proximity 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * some corrections - Jun-22-2003, martin schneebacher 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - Added support for the sysfs interface, deprecating the 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * procfs interface for 2.5.x kernel. Also added support for 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Wheel command. Bryan W. Headley July-15-2003. 3405f091ab4c8c1f12f8dd38ee789489904fea327dDmitry Torokhov * v1.2 - Reworked jitter timer as a kernel thread. 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bryan W. Headley November-28-2003/Jan-10-2004. 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * v1.3 - Repaired issue of kernel thread going nuts on single-processor 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * machines, introduced programmableDelay as a command line 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * parameter. Feb 7 2004, Bryan W. Headley. 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * v1.4 - Re-wire jitter so it does not require a thread. Courtesy of 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Rene van Paassen. Added reporting of physical pointer device 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (e.g., stylus, mouse in reports 2, 3, 4, 5. We don't know 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * for reports 1, 6.) 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * what physical device reports for reports 1, 6.) Also enabled 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * MOUSE and LENS tool button modes. Renamed "rubber" to "eraser". 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Feb 20, 2004, Bryan W. Headley. 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * v1.5 - Added previousJitterable, so we don't do jitter delay when the 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * user is holding a button down for periods of time. 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * NOTE: 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This kernel driver is augmented by the "Aiptek" XFree86 input 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * driver for your X server, as well as the Gaiptek GUI Front-end 5205f091ab4c8c1f12f8dd38ee789489904fea327dDmitry Torokhov * "Tablet Manager". 5305f091ab4c8c1f12f8dd38ee789489904fea327dDmitry Torokhov * These three products are highly interactive with one another, 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * so therefore it's easier to document them all as one subsystem. 5505f091ab4c8c1f12f8dd38ee789489904fea327dDmitry Torokhov * Please visit the project's "home page", located at, 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * http://aiptektablet.sourceforge.net. 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This program is free software; you can redistribute it and/or modify 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * it under the terms of the GNU General Public License as published by 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the Free Software Foundation; either version 2 of the License, or 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (at your option) any later version. 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This program is distributed in the hope that it will be useful, 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * but WITHOUT ANY WARRANTY; without even the implied warranty of 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * GNU General Public License for more details. 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * You should have received a copy of the GNU General Public License 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * along with this program; if not, write to the Free Software 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/jiffies.h> 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h> 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/slab.h> 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h> 77ae0dadcf0f912cbab2ac84caa437454620bf71b2David Brownell#include <linux/usb/input.h> 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/uaccess.h> 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/unaligned.h> 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Version Information 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 845035522d1a6b55f95e7e01c209b57f5d89f88b16Rene van Paassen#define DRIVER_VERSION "v2.3 (May 2, 2007)" 855035522d1a6b55f95e7e01c209b57f5d89f88b16Rene van Paassen#define DRIVER_AUTHOR "Bryan W. Headley/Chris Atenasio/Cedric Brun/Rene van Paassen" 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DRIVER_DESC "Aiptek HyperPen USB Tablet Driver (Linux 2.6.x)" 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Aiptek status packet: 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (returned as Report 1 - relative coordinates from mouse and stylus) 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * byte0 0 0 0 0 0 0 0 1 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * byte1 0 0 0 0 0 BS2 BS Tip 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * byte2 X7 X6 X5 X4 X3 X2 X1 X0 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * byte3 Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (returned as Report 2 - absolute coordinates from the stylus) 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * byte0 0 0 0 0 0 0 1 0 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * byte1 X7 X6 X5 X4 X3 X2 X1 X0 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * byte2 X15 X14 X13 X12 X11 X10 X9 X8 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * byte3 Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * byte4 Y15 Y14 Y13 Y12 Y11 Y10 Y9 Y8 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * byte5 * * * BS2 BS1 Tip IR DV 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * byte6 P7 P6 P5 P4 P3 P2 P1 P0 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * byte7 P15 P14 P13 P12 P11 P10 P9 P8 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (returned as Report 3 - absolute coordinates from the mouse) 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 1142fe574167be6a61d5f37c496da01c4a7daa73f4dRene van Paassen * byte0 0 0 0 0 0 0 1 1 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * byte1 X7 X6 X5 X4 X3 X2 X1 X0 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * byte2 X15 X14 X13 X12 X11 X10 X9 X8 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * byte3 Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * byte4 Y15 Y14 Y13 Y12 Y11 Y10 Y9 Y8 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * byte5 * * * BS2 BS1 Tip IR DV 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * byte6 P7 P6 P5 P4 P3 P2 P1 P0 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * byte7 P15 P14 P13 P12 P11 P10 P9 P8 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (returned as Report 4 - macrokeys from the stylus) 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * byte0 0 0 0 0 0 1 0 0 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * byte1 0 0 0 BS2 BS Tip IR DV 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * byte2 0 0 0 0 0 0 1 0 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * byte3 0 0 0 K4 K3 K2 K1 K0 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * byte4 P7 P6 P5 P4 P3 P2 P1 P0 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * byte5 P15 P14 P13 P12 P11 P10 P9 P8 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (returned as Report 5 - macrokeys from the mouse) 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 1362fe574167be6a61d5f37c496da01c4a7daa73f4dRene van Paassen * byte0 0 0 0 0 0 1 0 1 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * byte1 0 0 0 BS2 BS Tip IR DV 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * byte2 0 0 0 0 0 0 1 0 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * byte3 0 0 0 K4 K3 K2 K1 K0 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * byte4 P7 P6 P5 P4 P3 P2 P1 P0 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * byte5 P15 P14 P13 P12 P11 P10 P9 P8 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * IR: In Range = Proximity on 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * DV = Data Valid 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * BS = Barrel Switch (as in, macro keys) 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * BS2 also referred to as Tablet Pick 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Command Summary: 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Use report_type CONTROL (3) 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Use report_id 2 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Command/Data Description Return Bytes Return Value 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0x10/0x00 SwitchToMouse 0 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0x10/0x01 SwitchToTablet 0 15605f091ab4c8c1f12f8dd38ee789489904fea327dDmitry Torokhov * 0x18/0x04 SetResolution 0 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0x12/0xFF AutoGainOn 0 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0x17/0x00 FilterOn 0 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0x01/0x00 GetXExtension 2 MaxX 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0x01/0x01 GetYExtension 2 MaxY 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0x02/0x00 GetModelCode 2 ModelCode = LOBYTE 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0x03/0x00 GetODMCode 2 ODMCode 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0x08/0x00 GetPressureLevels 2 =512 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0x04/0x00 GetFirmwareVersion 2 Firmware Version 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0x11/0x02 EnableMacroKeys 0 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * To initialize the tablet: 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (1) Send Resolution500LPI (Command) 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (2) Query for Model code (Option Report) 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (3) Query for ODM code (Option Report) 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (4) Query for firmware (Option Report) 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (5) Query for GetXExtension (Option Report) 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (6) Query for GetYExtension (Option Report) 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (7) Query for GetPressureLevels (Option Report) 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (8) SwitchToTablet for Absolute coordinates, or 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * SwitchToMouse for Relative coordinates (Command) 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (9) EnableMacroKeys (Command) 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (10) FilterOn (Command) 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (11) AutoGainOn (Command) 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (Step 9 can be omitted, but you'll then have no function keys.) 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define USB_VENDOR_ID_AIPTEK 0x08ca 186a32bcc45b9e9d8021b5936c45dc3f8db7a044466Guryanov Dmitry#define USB_VENDOR_ID_KYE 0x0458 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define USB_REQ_GET_REPORT 0x01 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define USB_REQ_SET_REPORT 0x09 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* PointerMode codes 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AIPTEK_POINTER_ONLY_MOUSE_MODE 0 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AIPTEK_POINTER_ONLY_STYLUS_MODE 1 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AIPTEK_POINTER_EITHER_MODE 2 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AIPTEK_POINTER_ALLOW_MOUSE_MODE(a) \ 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (a == AIPTEK_POINTER_ONLY_MOUSE_MODE || \ 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds a == AIPTEK_POINTER_EITHER_MODE) 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AIPTEK_POINTER_ALLOW_STYLUS_MODE(a) \ 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (a == AIPTEK_POINTER_ONLY_STYLUS_MODE || \ 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds a == AIPTEK_POINTER_EITHER_MODE) 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* CoordinateMode code 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AIPTEK_COORDINATE_RELATIVE_MODE 0 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AIPTEK_COORDINATE_ABSOLUTE_MODE 1 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* XTilt and YTilt values 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AIPTEK_TILT_MIN (-128) 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AIPTEK_TILT_MAX 127 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AIPTEK_TILT_DISABLE (-10101) 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Wheel values 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AIPTEK_WHEEL_MIN 0 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AIPTEK_WHEEL_MAX 1024 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AIPTEK_WHEEL_DISABLE (-10101) 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* ToolCode values, which BTW are 0x140 .. 0x14f 221b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen * We have things set up such that if the tool button has changed, 222b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen * the tools get reset. 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* toolMode codes 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AIPTEK_TOOL_BUTTON_PEN_MODE BTN_TOOL_PEN 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AIPTEK_TOOL_BUTTON_PENCIL_MODE BTN_TOOL_PENCIL 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AIPTEK_TOOL_BUTTON_BRUSH_MODE BTN_TOOL_BRUSH 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AIPTEK_TOOL_BUTTON_AIRBRUSH_MODE BTN_TOOL_AIRBRUSH 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AIPTEK_TOOL_BUTTON_ERASER_MODE BTN_TOOL_RUBBER 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AIPTEK_TOOL_BUTTON_MOUSE_MODE BTN_TOOL_MOUSE 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AIPTEK_TOOL_BUTTON_LENS_MODE BTN_TOOL_LENS 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Diagnostic message codes 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AIPTEK_DIAGNOSTIC_NA 0 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AIPTEK_DIAGNOSTIC_SENDING_RELATIVE_IN_ABSOLUTE 1 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AIPTEK_DIAGNOSTIC_SENDING_ABSOLUTE_IN_RELATIVE 2 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AIPTEK_DIAGNOSTIC_TOOL_DISALLOWED 3 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 24105f091ab4c8c1f12f8dd38ee789489904fea327dDmitry Torokhov /* Time to wait (in ms) to help mask hand jittering 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * when pressing the stylus buttons. 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AIPTEK_JITTER_DELAY_DEFAULT 50 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Time to wait (in ms) in-between sending the tablet 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * a command and beginning the process of reading the return 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * sequence from the tablet. 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AIPTEK_PROGRAMMABLE_DELAY_25 25 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AIPTEK_PROGRAMMABLE_DELAY_50 50 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AIPTEK_PROGRAMMABLE_DELAY_100 100 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AIPTEK_PROGRAMMABLE_DELAY_200 200 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AIPTEK_PROGRAMMABLE_DELAY_300 300 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AIPTEK_PROGRAMMABLE_DELAY_400 400 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AIPTEK_PROGRAMMABLE_DELAY_DEFAULT AIPTEK_PROGRAMMABLE_DELAY_400 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Mouse button programming 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 260ce0982edaec2c46dc9ec466e03f1fe94ee0862d8Rene van Paassen#define AIPTEK_MOUSE_LEFT_BUTTON 0x04 261ce0982edaec2c46dc9ec466e03f1fe94ee0862d8Rene van Paassen#define AIPTEK_MOUSE_RIGHT_BUTTON 0x08 262ce0982edaec2c46dc9ec466e03f1fe94ee0862d8Rene van Paassen#define AIPTEK_MOUSE_MIDDLE_BUTTON 0x10 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Stylus button programming 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AIPTEK_STYLUS_LOWER_BUTTON 0x08 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AIPTEK_STYLUS_UPPER_BUTTON 0x10 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Length of incoming packet from the tablet 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AIPTEK_PACKET_LENGTH 8 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* We report in EV_MISC both the proximity and 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * whether the report came from the stylus, tablet mouse 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * or "unknown" -- Unknown when the tablet is in relative 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * mode, because we only get report 1's. 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AIPTEK_REPORT_TOOL_UNKNOWN 0x10 2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AIPTEK_REPORT_TOOL_STYLUS 0x20 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AIPTEK_REPORT_TOOL_MOUSE 0x40 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int programmableDelay = AIPTEK_PROGRAMMABLE_DELAY_DEFAULT; 2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int jitterDelay = AIPTEK_JITTER_DELAY_DEFAULT; 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct aiptek_features { 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int odmCode; /* Tablet manufacturer code */ 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int modelCode; /* Tablet model code (not unique) */ 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int firmwareCode; /* prom/eeprom version */ 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char usbPath[64 + 1]; /* device's physical usb path */ 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct aiptek_settings { 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int pointerMode; /* stylus-, mouse-only or either */ 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int coordinateMode; /* absolute/relative coords */ 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int toolMode; /* pen, pencil, brush, etc. tool */ 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int xTilt; /* synthetic xTilt amount */ 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int yTilt; /* synthetic yTilt amount */ 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int wheel; /* synthetic wheel amount */ 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int stylusButtonUpper; /* stylus upper btn delivers... */ 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int stylusButtonLower; /* stylus lower btn delivers... */ 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int mouseButtonLeft; /* mouse left btn delivers... */ 3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int mouseButtonMiddle; /* mouse middle btn delivers... */ 3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int mouseButtonRight; /* mouse right btn delivers... */ 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int programmableDelay; /* delay for tablet programming */ 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int jitterDelay; /* delay for hand jittering */ 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct aiptek { 309c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov struct input_dev *inputdev; /* input device struct */ 3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct usb_device *usbdev; /* usb device struct */ 311871ba51c130d4f2e7d33b8c57e834df701357102Greg Kroah-Hartman struct usb_interface *intf; /* usb interface struct */ 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct urb *urb; /* urb for incoming reports */ 3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dma_addr_t data_dma; /* our dma stuffage */ 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct aiptek_features features; /* tablet's array of features */ 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct aiptek_settings curSetting; /* tablet's current programmable */ 3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct aiptek_settings newSetting; /* ... and new param settings */ 3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int ifnum; /* interface number for IO */ 3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int diagnostic; /* tablet diagnostic codes */ 3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long eventCount; /* event count */ 3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int inDelay; /* jitter: in jitter delay? */ 3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long endDelay; /* jitter: time when delay ends */ 3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int previousJitterable; /* jitterable prev value */ 323b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen 324b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen int lastMacro; /* macro key to reset */ 325b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen int previousToolMode; /* pen, pencil, brush, etc. tool */ 3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char *data; /* incoming packet data */ 3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3291a54f49e8989462cfc9cab0c377b2d4e60e5b70aRene van Paassenstatic const int eventTypes[] = { 3301a54f49e8989462cfc9cab0c377b2d4e60e5b70aRene van Paassen EV_KEY, EV_ABS, EV_REL, EV_MSC, 3311a54f49e8989462cfc9cab0c377b2d4e60e5b70aRene van Paassen}; 3321a54f49e8989462cfc9cab0c377b2d4e60e5b70aRene van Paassen 3331a54f49e8989462cfc9cab0c377b2d4e60e5b70aRene van Paassenstatic const int absEvents[] = { 3341a54f49e8989462cfc9cab0c377b2d4e60e5b70aRene van Paassen ABS_X, ABS_Y, ABS_PRESSURE, ABS_TILT_X, ABS_TILT_Y, 3351a54f49e8989462cfc9cab0c377b2d4e60e5b70aRene van Paassen ABS_WHEEL, ABS_MISC, 3361a54f49e8989462cfc9cab0c377b2d4e60e5b70aRene van Paassen}; 3371a54f49e8989462cfc9cab0c377b2d4e60e5b70aRene van Paassen 3381a54f49e8989462cfc9cab0c377b2d4e60e5b70aRene van Paassenstatic const int relEvents[] = { 3391a54f49e8989462cfc9cab0c377b2d4e60e5b70aRene van Paassen REL_X, REL_Y, REL_WHEEL, 3401a54f49e8989462cfc9cab0c377b2d4e60e5b70aRene van Paassen}; 3411a54f49e8989462cfc9cab0c377b2d4e60e5b70aRene van Paassen 34233936fa603f2524a7dde08d22637d0989a4e8fddDmitry Torokhovstatic const int buttonEvents[] = { 34333936fa603f2524a7dde08d22637d0989a4e8fddDmitry Torokhov BTN_LEFT, BTN_RIGHT, BTN_MIDDLE, 34433936fa603f2524a7dde08d22637d0989a4e8fddDmitry Torokhov BTN_TOOL_PEN, BTN_TOOL_RUBBER, BTN_TOOL_PENCIL, BTN_TOOL_AIRBRUSH, 34533936fa603f2524a7dde08d22637d0989a4e8fddDmitry Torokhov BTN_TOOL_BRUSH, BTN_TOOL_MOUSE, BTN_TOOL_LENS, BTN_TOUCH, 34633936fa603f2524a7dde08d22637d0989a4e8fddDmitry Torokhov BTN_STYLUS, BTN_STYLUS2, 34733936fa603f2524a7dde08d22637d0989a4e8fddDmitry Torokhov}; 34833936fa603f2524a7dde08d22637d0989a4e8fddDmitry Torokhov 3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Permit easy lookup of keyboard events to send, versus 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the bitmap which comes from the tablet. This hides the 3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * issue that the F_keys are not sequentially numbered. 3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3544c4c9432a6c916729c7296c47fe93b053a73e20cArjan van de Venstatic const int macroKeyEvents[] = { 3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds KEY_ESC, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, 3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_F11, 3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds KEY_F12, KEY_F13, KEY_F14, KEY_F15, KEY_F16, KEY_F17, 3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds KEY_F18, KEY_F19, KEY_F20, KEY_F21, KEY_F22, KEY_F23, 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds KEY_F24, KEY_STOP, KEY_AGAIN, KEY_PROPS, KEY_UNDO, 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds KEY_FRONT, KEY_COPY, KEY_OPEN, KEY_PASTE, 0 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*********************************************************************** 364c9404c9c392d557a4687c4cbda022b03cb787ce9Adam Buchbinder * Map values to strings and back. Every map should have the following 365cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov * as its last element: { NULL, AIPTEK_INVALID_VALUE }. 366cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov */ 367cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov#define AIPTEK_INVALID_VALUE -1 368cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov 369cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhovstruct aiptek_map { 370cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov const char *string; 371cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov int value; 372cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov}; 373cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov 374cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhovstatic int map_str_to_val(const struct aiptek_map *map, const char *str, size_t count) 375cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov{ 376cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov const struct aiptek_map *p; 377cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov 3780112db36ef95e5632db071297f7df130725c47b9Rene van Paassen if (str[count - 1] == '\n') 3790112db36ef95e5632db071297f7df130725c47b9Rene van Paassen count--; 3800112db36ef95e5632db071297f7df130725c47b9Rene van Paassen 381cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov for (p = map; p->string; p++) 3820112db36ef95e5632db071297f7df130725c47b9Rene van Paassen if (!strncmp(str, p->string, count)) 383cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov return p->value; 384cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov 385cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov return AIPTEK_INVALID_VALUE; 386cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov} 387cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov 388cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhovstatic const char *map_val_to_str(const struct aiptek_map *map, int val) 389cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov{ 390cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov const struct aiptek_map *p; 391cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov 392cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov for (p = map; p->value != AIPTEK_INVALID_VALUE; p++) 393cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov if (val == p->value) 394cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov return p->string; 395cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov 396cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov return "unknown"; 397cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov} 398cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov 399cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov/*********************************************************************** 4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * aiptek_irq can receive one of six potential reports. 4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The documentation for each is in the body of the function. 4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The tablet reports on several attributes per invocation of 4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * aiptek_irq. Because the Linux Input Event system allows the 4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * transmission of ONE attribute per input_report_xxx() call, 4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * collation has to be done on the other end to reconstitute 4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * a complete tablet report. Further, the number of Input Event reports 4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * submitted varies, depending on what USB report type, and circumstance. 4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * To deal with this, EV_MSC is used to indicate an 'end-of-report' 4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * message. This has been an undocumented convention understood by the kernel 4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * tablet driver and clients such as gpm and XFree86's tablet drivers. 4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Of the information received from the tablet, the one piece I 4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * cannot transmit is the proximity bit (without resorting to an EV_MSC 4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * convention above.) I therefore have taken over REL_MISC and ABS_MISC 4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (for relative and absolute reports, respectively) for communicating 4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Proximity. Why two events? I thought it interesting to know if the 418093cf723b2b06d774929ea07982f6a466ff22314Steven Cole * Proximity event occurred while the tablet was in absolute or relative 4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * mode. 420da9fda434cde76dfb8174548a63b685b4ac00a9cRene van Paassen * Update: REL_MISC proved not to be such a good idea. With REL_MISC you 421da9fda434cde76dfb8174548a63b685b4ac00a9cRene van Paassen * get an event transmitted each time. ABS_MISC works better, since it 422da9fda434cde76dfb8174548a63b685b4ac00a9cRene van Paassen * can be set and re-set. Thus, only using ABS_MISC from now on. 4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Other tablets use the notion of a certain minimum stylus pressure 4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * to infer proximity. While that could have been done, that is yet 4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * another 'by convention' behavior, the documentation for which 4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * would be spread between two (or more) pieces of software. 4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * EV_MSC usage was terminated for this purpose in Linux 2.5.x, and 4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * replaced with the input_sync() method (which emits EV_SYN.) 4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4337d12e780e003f93433d49ce78cfedf4b4c52adc5David Howellsstatic void aiptek_irq(struct urb *urb) 4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct aiptek *aiptek = urb->context; 4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char *data = aiptek->data; 437c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov struct input_dev *inputdev = aiptek->inputdev; 438871ba51c130d4f2e7d33b8c57e834df701357102Greg Kroah-Hartman struct usb_interface *intf = aiptek->intf; 4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int jitterable = 0; 4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int retval, macro, x, y, z, left, right, middle, p, dv, tip, bs, pck; 4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (urb->status) { 4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0: 4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Success */ 4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case -ECONNRESET: 4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case -ENOENT: 4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case -ESHUTDOWN: 4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* This urb is terminated, clean up */ 451871ba51c130d4f2e7d33b8c57e834df701357102Greg Kroah-Hartman dev_dbg(&intf->dev, "%s - urb shutting down with status: %d\n", 4528fb6321b6bd9ebcc03243f27fe98e18e246a5c97Greg Kroah-Hartman __func__, urb->status); 4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 456871ba51c130d4f2e7d33b8c57e834df701357102Greg Kroah-Hartman dev_dbg(&intf->dev, "%s - nonzero urb status received: %d\n", 4578fb6321b6bd9ebcc03243f27fe98e18e246a5c97Greg Kroah-Hartman __func__, urb->status); 4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto exit; 4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* See if we are in a delay loop -- throw out report if true. 4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (aiptek->inDelay == 1 && time_after(aiptek->endDelay, jiffies)) { 4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto exit; 4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->inDelay = 0; 4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->eventCount++; 4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Report 1 delivers relative coordinates with either a stylus 4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * or the mouse. You do not know, however, which input 4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * tool generated the event. 4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (data[0] == 1) { 4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (aiptek->curSetting.coordinateMode == 4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds AIPTEK_COORDINATE_ABSOLUTE_MODE) { 4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->diagnostic = 4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds AIPTEK_DIAGNOSTIC_SENDING_RELATIVE_IN_ABSOLUTE; 4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 48037767b66ed61ee37f0d8f40523f74c31bc187d1dDmitry Torokhov x = (signed char) data[2]; 48137767b66ed61ee37f0d8f40523f74c31bc187d1dDmitry Torokhov y = (signed char) data[3]; 4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* jitterable keeps track of whether any button has been pressed. 4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * We're also using it to remap the physical mouse button mask 4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * to pseudo-settings. (We don't specifically care about it's 4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * value after moving/transposing mouse button bitmasks, except 4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * that a non-zero value indicates that one or more 4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * mouse button was pressed.) 4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4900038cae0ffd72b75699010bd112655dc2615e2fdMark Vytlacil jitterable = data[1] & 0x07; 4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4920038cae0ffd72b75699010bd112655dc2615e2fdMark Vytlacil left = (data[1] & aiptek->curSetting.mouseButtonLeft >> 2) != 0 ? 1 : 0; 4930038cae0ffd72b75699010bd112655dc2615e2fdMark Vytlacil right = (data[1] & aiptek->curSetting.mouseButtonRight >> 2) != 0 ? 1 : 0; 4940038cae0ffd72b75699010bd112655dc2615e2fdMark Vytlacil middle = (data[1] & aiptek->curSetting.mouseButtonMiddle >> 2) != 0 ? 1 : 0; 4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds input_report_key(inputdev, BTN_LEFT, left); 4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds input_report_key(inputdev, BTN_MIDDLE, middle); 4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds input_report_key(inputdev, BTN_RIGHT, right); 4990038cae0ffd72b75699010bd112655dc2615e2fdMark Vytlacil 5000038cae0ffd72b75699010bd112655dc2615e2fdMark Vytlacil input_report_abs(inputdev, ABS_MISC, 5010038cae0ffd72b75699010bd112655dc2615e2fdMark Vytlacil 1 | AIPTEK_REPORT_TOOL_UNKNOWN); 5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds input_report_rel(inputdev, REL_X, x); 5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds input_report_rel(inputdev, REL_Y, y); 5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Wheel support is in the form of a single-event 5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * firing. 5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (aiptek->curSetting.wheel != AIPTEK_WHEEL_DISABLE) { 5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds input_report_rel(inputdev, REL_WHEEL, 5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->curSetting.wheel); 5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->curSetting.wheel = AIPTEK_WHEEL_DISABLE; 5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5131e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen if (aiptek->lastMacro != -1) { 5141e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen input_report_key(inputdev, 5151e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen macroKeyEvents[aiptek->lastMacro], 0); 5161e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen aiptek->lastMacro = -1; 5171e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen } 5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds input_sync(inputdev); 5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Report 2 is delivered only by the stylus, and delivers 5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * absolute coordinates. 5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (data[0] == 2) { 5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (aiptek->curSetting.coordinateMode == AIPTEK_COORDINATE_RELATIVE_MODE) { 5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->diagnostic = AIPTEK_DIAGNOSTIC_SENDING_ABSOLUTE_IN_RELATIVE; 5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (!AIPTEK_POINTER_ALLOW_STYLUS_MODE 5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (aiptek->curSetting.pointerMode)) { 5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->diagnostic = AIPTEK_DIAGNOSTIC_TOOL_DISALLOWED; 5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 531858ad08cf4c32a51d26552d3cb5fa8d5e2f0e579Harvey Harrison x = get_unaligned_le16(data + 1); 532858ad08cf4c32a51d26552d3cb5fa8d5e2f0e579Harvey Harrison y = get_unaligned_le16(data + 3); 533858ad08cf4c32a51d26552d3cb5fa8d5e2f0e579Harvey Harrison z = get_unaligned_le16(data + 6); 5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 535fe981f2340edffcb6aad2203d8f14c9bef0e67e3Rene van Paassen dv = (data[5] & 0x01) != 0 ? 1 : 0; 536fe981f2340edffcb6aad2203d8f14c9bef0e67e3Rene van Paassen p = (data[5] & 0x02) != 0 ? 1 : 0; 5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tip = (data[5] & 0x04) != 0 ? 1 : 0; 5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Use jitterable to re-arrange button masks 5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 5411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds jitterable = data[5] & 0x18; 5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bs = (data[5] & aiptek->curSetting.stylusButtonLower) != 0 ? 1 : 0; 5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pck = (data[5] & aiptek->curSetting.stylusButtonUpper) != 0 ? 1 : 0; 5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* dv indicates 'data valid' (e.g., the tablet is in sync 5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * and has delivered a "correct" report) We will ignore 5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * all 'bad' reports... 5491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dv != 0) { 551b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen /* If the selected tool changed, reset the old 552b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen * tool key, and set the new one. 5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 554b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen if (aiptek->previousToolMode != 555b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen aiptek->curSetting.toolMode) { 556b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen input_report_key(inputdev, 557b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen aiptek->previousToolMode, 0); 5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds input_report_key(inputdev, 559b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen aiptek->curSetting.toolMode, 5601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1); 561b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen aiptek->previousToolMode = 562b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen aiptek->curSetting.toolMode; 5631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (p != 0) { 5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds input_report_abs(inputdev, ABS_X, x); 5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds input_report_abs(inputdev, ABS_Y, y); 5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds input_report_abs(inputdev, ABS_PRESSURE, z); 5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds input_report_key(inputdev, BTN_TOUCH, tip); 5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds input_report_key(inputdev, BTN_STYLUS, bs); 5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds input_report_key(inputdev, BTN_STYLUS2, pck); 5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (aiptek->curSetting.xTilt != 5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds AIPTEK_TILT_DISABLE) { 5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds input_report_abs(inputdev, 5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ABS_TILT_X, 5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->curSetting.xTilt); 5791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (aiptek->curSetting.yTilt != AIPTEK_TILT_DISABLE) { 5811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds input_report_abs(inputdev, 5821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ABS_TILT_Y, 5831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->curSetting.yTilt); 5841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Wheel support is in the form of a single-event 5871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * firing. 5881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 5891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (aiptek->curSetting.wheel != 5901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds AIPTEK_WHEEL_DISABLE) { 5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds input_report_abs(inputdev, 5921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ABS_WHEEL, 5931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->curSetting.wheel); 5941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->curSetting.wheel = AIPTEK_WHEEL_DISABLE; 5951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds input_report_abs(inputdev, ABS_MISC, p | AIPTEK_REPORT_TOOL_STYLUS); 5981e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen if (aiptek->lastMacro != -1) { 5991e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen input_report_key(inputdev, 6001e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen macroKeyEvents[aiptek->lastMacro], 0); 6011e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen aiptek->lastMacro = -1; 6021e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen } 6031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds input_sync(inputdev); 6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Report 3's come from the mouse in absolute mode. 6081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 6091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (data[0] == 3) { 6101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (aiptek->curSetting.coordinateMode == AIPTEK_COORDINATE_RELATIVE_MODE) { 6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->diagnostic = AIPTEK_DIAGNOSTIC_SENDING_ABSOLUTE_IN_RELATIVE; 6121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (!AIPTEK_POINTER_ALLOW_MOUSE_MODE 6131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (aiptek->curSetting.pointerMode)) { 6141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->diagnostic = AIPTEK_DIAGNOSTIC_TOOL_DISALLOWED; 6151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 616858ad08cf4c32a51d26552d3cb5fa8d5e2f0e579Harvey Harrison x = get_unaligned_le16(data + 1); 617858ad08cf4c32a51d26552d3cb5fa8d5e2f0e579Harvey Harrison y = get_unaligned_le16(data + 3); 6181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds jitterable = data[5] & 0x1c; 6201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 621fe981f2340edffcb6aad2203d8f14c9bef0e67e3Rene van Paassen dv = (data[5] & 0x01) != 0 ? 1 : 0; 622fe981f2340edffcb6aad2203d8f14c9bef0e67e3Rene van Paassen p = (data[5] & 0x02) != 0 ? 1 : 0; 6231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds left = (data[5] & aiptek->curSetting.mouseButtonLeft) != 0 ? 1 : 0; 6241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds right = (data[5] & aiptek->curSetting.mouseButtonRight) != 0 ? 1 : 0; 6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds middle = (data[5] & aiptek->curSetting.mouseButtonMiddle) != 0 ? 1 : 0; 6261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dv != 0) { 628b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen /* If the selected tool changed, reset the old 629b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen * tool key, and set the new one. 6301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 631b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen if (aiptek->previousToolMode != 632b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen aiptek->curSetting.toolMode) { 633b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen input_report_key(inputdev, 634b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen aiptek->previousToolMode, 0); 6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds input_report_key(inputdev, 636b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen aiptek->curSetting.toolMode, 6371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1); 638b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen aiptek->previousToolMode = 639b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen aiptek->curSetting.toolMode; 6401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (p != 0) { 6431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds input_report_abs(inputdev, ABS_X, x); 6441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds input_report_abs(inputdev, ABS_Y, y); 6451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds input_report_key(inputdev, BTN_LEFT, left); 6471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds input_report_key(inputdev, BTN_MIDDLE, middle); 6481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds input_report_key(inputdev, BTN_RIGHT, right); 6491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Wheel support is in the form of a single-event 6511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * firing. 6521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 6531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (aiptek->curSetting.wheel != AIPTEK_WHEEL_DISABLE) { 6541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds input_report_abs(inputdev, 6551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ABS_WHEEL, 6561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->curSetting.wheel); 6571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->curSetting.wheel = AIPTEK_WHEEL_DISABLE; 6581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 660da9fda434cde76dfb8174548a63b685b4ac00a9cRene van Paassen input_report_abs(inputdev, ABS_MISC, p | AIPTEK_REPORT_TOOL_MOUSE); 6611e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen if (aiptek->lastMacro != -1) { 6621e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen input_report_key(inputdev, 6631e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen macroKeyEvents[aiptek->lastMacro], 0); 6641e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen aiptek->lastMacro = -1; 6651e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen } 6661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds input_sync(inputdev); 6671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Report 4s come from the macro keys when pressed by stylus 6711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 6721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (data[0] == 4) { 6731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds jitterable = data[1] & 0x18; 6741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 675fe981f2340edffcb6aad2203d8f14c9bef0e67e3Rene van Paassen dv = (data[1] & 0x01) != 0 ? 1 : 0; 676fe981f2340edffcb6aad2203d8f14c9bef0e67e3Rene van Paassen p = (data[1] & 0x02) != 0 ? 1 : 0; 6771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tip = (data[1] & 0x04) != 0 ? 1 : 0; 6781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bs = (data[1] & aiptek->curSetting.stylusButtonLower) != 0 ? 1 : 0; 6791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pck = (data[1] & aiptek->curSetting.stylusButtonUpper) != 0 ? 1 : 0; 6801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6811e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen macro = dv && p && tip && !(data[3] & 1) ? (data[3] >> 1) : -1; 682858ad08cf4c32a51d26552d3cb5fa8d5e2f0e579Harvey Harrison z = get_unaligned_le16(data + 4); 6831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6841e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen if (dv) { 685b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen /* If the selected tool changed, reset the old 686b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen * tool key, and set the new one. 6871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 688b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen if (aiptek->previousToolMode != 689b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen aiptek->curSetting.toolMode) { 690b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen input_report_key(inputdev, 691b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen aiptek->previousToolMode, 0); 6921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds input_report_key(inputdev, 693b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen aiptek->curSetting.toolMode, 6941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1); 695b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen aiptek->previousToolMode = 696b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen aiptek->curSetting.toolMode; 6971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6981e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen } 6991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7001e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen if (aiptek->lastMacro != -1 && aiptek->lastMacro != macro) { 7011e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen input_report_key(inputdev, macroKeyEvents[aiptek->lastMacro], 0); 7021e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen aiptek->lastMacro = -1; 7031e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen } 7041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7051e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen if (macro != -1 && macro != aiptek->lastMacro) { 7061e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen input_report_key(inputdev, macroKeyEvents[macro], 1); 7071e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen aiptek->lastMacro = macro; 7081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7091e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen input_report_abs(inputdev, ABS_MISC, 7101e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen p | AIPTEK_REPORT_TOOL_STYLUS); 7111e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen input_sync(inputdev); 7121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Report 5s come from the macro keys when pressed by mouse 7141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 7151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (data[0] == 5) { 7161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds jitterable = data[1] & 0x1c; 7171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 718fe981f2340edffcb6aad2203d8f14c9bef0e67e3Rene van Paassen dv = (data[1] & 0x01) != 0 ? 1 : 0; 719fe981f2340edffcb6aad2203d8f14c9bef0e67e3Rene van Paassen p = (data[1] & 0x02) != 0 ? 1 : 0; 7201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds left = (data[1]& aiptek->curSetting.mouseButtonLeft) != 0 ? 1 : 0; 7211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds right = (data[1] & aiptek->curSetting.mouseButtonRight) != 0 ? 1 : 0; 7221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds middle = (data[1] & aiptek->curSetting.mouseButtonMiddle) != 0 ? 1 : 0; 7231e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen macro = dv && p && left && !(data[3] & 1) ? (data[3] >> 1) : 0; 7241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7251e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen if (dv) { 726b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen /* If the selected tool changed, reset the old 727b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen * tool key, and set the new one. 7281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 729b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen if (aiptek->previousToolMode != 730b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen aiptek->curSetting.toolMode) { 7311e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen input_report_key(inputdev, 732b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen aiptek->previousToolMode, 0); 7331e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen input_report_key(inputdev, 7341e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen aiptek->curSetting.toolMode, 1); 7351e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen aiptek->previousToolMode = aiptek->curSetting.toolMode; 7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7371e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen } 7381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7391e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen if (aiptek->lastMacro != -1 && aiptek->lastMacro != macro) { 7401e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen input_report_key(inputdev, macroKeyEvents[aiptek->lastMacro], 0); 7411e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen aiptek->lastMacro = -1; 7421e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen } 7431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7441e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen if (macro != -1 && macro != aiptek->lastMacro) { 7451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds input_report_key(inputdev, macroKeyEvents[macro], 1); 7461e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen aiptek->lastMacro = macro; 7471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7481e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen 7491e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen input_report_abs(inputdev, ABS_MISC, 7501e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen p | AIPTEK_REPORT_TOOL_MOUSE); 7511e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen input_sync(inputdev); 7521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* We have no idea which tool can generate a report 6. Theoretically, 7541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * neither need to, having been given reports 4 & 5 for such use. 7551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * However, report 6 is the 'official-looking' report for macroKeys; 7561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * reports 4 & 5 supposively are used to support unnamed, unknown 7571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hat switches (which just so happen to be the macroKeys.) 7581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 7591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (data[0] == 6) { 760858ad08cf4c32a51d26552d3cb5fa8d5e2f0e579Harvey Harrison macro = get_unaligned_le16(data + 1); 7611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (macro > 0) { 7621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds input_report_key(inputdev, macroKeyEvents[macro - 1], 7631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0); 7641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (macro < 25) { 7661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds input_report_key(inputdev, macroKeyEvents[macro + 1], 7671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0); 7681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 770b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen /* If the selected tool changed, reset the old 771b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen tool key, and set the new one. 772b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen */ 773b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen if (aiptek->previousToolMode != 774b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen aiptek->curSetting.toolMode) { 775b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen input_report_key(inputdev, 776b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen aiptek->previousToolMode, 0); 7771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds input_report_key(inputdev, 778b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen aiptek->curSetting.toolMode, 779b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen 1); 780b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen aiptek->previousToolMode = 781b3b6cf1d47508a04de859d357789a3fc0cf8c690Rene van Paassen aiptek->curSetting.toolMode; 7821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds input_report_key(inputdev, macroKeyEvents[macro], 1); 7851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds input_report_abs(inputdev, ABS_MISC, 7861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1 | AIPTEK_REPORT_TOOL_UNKNOWN); 7871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds input_sync(inputdev); 7881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 789871ba51c130d4f2e7d33b8c57e834df701357102Greg Kroah-Hartman dev_dbg(&intf->dev, "Unknown report %d\n", data[0]); 7901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Jitter may occur when the user presses a button on the stlyus 7931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * or the mouse. What we do to prevent that is wait 'x' milliseconds 7941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * following a 'jitterable' event, which should give the hand some time 7951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * stabilize itself. 7961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 7971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * We just introduced aiptek->previousJitterable to carry forth the 7981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * notion that jitter occurs when the button state changes from on to off: 7991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * a person drawing, holding a button down is not subject to jittering. 8001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * With that in mind, changing from upper button depressed to lower button 8011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * WILL transition through a jitter delay. 8021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 8031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (aiptek->previousJitterable != jitterable && 8051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->curSetting.jitterDelay != 0 && aiptek->inDelay != 1) { 8061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->endDelay = jiffies + 8071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ((aiptek->curSetting.jitterDelay * HZ) / 1000); 8081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->inDelay = 1; 8091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->previousJitterable = jitterable; 8111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsexit: 8131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retval = usb_submit_urb(urb, GFP_ATOMIC); 8141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (retval != 0) { 815871ba51c130d4f2e7d33b8c57e834df701357102Greg Kroah-Hartman dev_err(&intf->dev, 8161f80bb943d755d48b894c677097fd80c7d7cce16Greg Kroah-Hartman "%s - usb_submit_urb failed with result %d\n", 8171f80bb943d755d48b894c677097fd80c7d7cce16Greg Kroah-Hartman __func__, retval); 8181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*********************************************************************** 8221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * These are the USB id's known so far. We do not identify them to 8231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * specific Aiptek model numbers, because there has been overlaps, 8241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * use, and reuse of id's in existing models. Certain models have 8251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * been known to use more than one ID, indicative perhaps of 82605f091ab4c8c1f12f8dd38ee789489904fea327dDmitry Torokhov * manufacturing revisions. In any event, we consider these 8271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * IDs to not be model-specific nor unique. 8281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 8291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic const struct usb_device_id aiptek_ids[] = { 8301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {USB_DEVICE(USB_VENDOR_ID_AIPTEK, 0x01)}, 8311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {USB_DEVICE(USB_VENDOR_ID_AIPTEK, 0x10)}, 8321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {USB_DEVICE(USB_VENDOR_ID_AIPTEK, 0x20)}, 8331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {USB_DEVICE(USB_VENDOR_ID_AIPTEK, 0x21)}, 8341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {USB_DEVICE(USB_VENDOR_ID_AIPTEK, 0x22)}, 8351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {USB_DEVICE(USB_VENDOR_ID_AIPTEK, 0x23)}, 8361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {USB_DEVICE(USB_VENDOR_ID_AIPTEK, 0x24)}, 837a32bcc45b9e9d8021b5936c45dc3f8db7a044466Guryanov Dmitry {USB_DEVICE(USB_VENDOR_ID_KYE, 0x5003)}, 8381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {} 8391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 8401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_DEVICE_TABLE(usb, aiptek_ids); 8421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*********************************************************************** 8441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Open an instance of the tablet driver. 8451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 8461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int aiptek_open(struct input_dev *inputdev) 8471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8487791bdae71243050132ede7ea1558c828b69458fDmitry Torokhov struct aiptek *aiptek = input_get_drvdata(inputdev); 8491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->urb->dev = aiptek->usbdev; 85165cde54b8b0299d7e46b8705338b01d1e44a5eb0Dmitry Torokhov if (usb_submit_urb(aiptek->urb, GFP_KERNEL) != 0) 8521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EIO; 8531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 8551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*********************************************************************** 8581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Close an instance of the tablet driver. 8591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 8601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void aiptek_close(struct input_dev *inputdev) 8611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8627791bdae71243050132ede7ea1558c828b69458fDmitry Torokhov struct aiptek *aiptek = input_get_drvdata(inputdev); 8631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 86465cde54b8b0299d7e46b8705338b01d1e44a5eb0Dmitry Torokhov usb_kill_urb(aiptek->urb); 8651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*********************************************************************** 86805f091ab4c8c1f12f8dd38ee789489904fea327dDmitry Torokhov * aiptek_set_report and aiptek_get_report() are borrowed from Linux 2.4.x, 8691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * where they were known as usb_set_report and usb_get_report. 8701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 8711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int 8721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsaiptek_set_report(struct aiptek *aiptek, 8731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char report_type, 8741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char report_id, void *buffer, int size) 8751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return usb_control_msg(aiptek->usbdev, 8771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds usb_sndctrlpipe(aiptek->usbdev, 0), 8781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds USB_REQ_SET_REPORT, 8791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds USB_TYPE_CLASS | USB_RECIP_INTERFACE | 8801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds USB_DIR_OUT, (report_type << 8) + report_id, 8811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->ifnum, buffer, size, 5000); 8821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int 8851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsaiptek_get_report(struct aiptek *aiptek, 8861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char report_type, 8871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char report_id, void *buffer, int size) 8881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return usb_control_msg(aiptek->usbdev, 8901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds usb_rcvctrlpipe(aiptek->usbdev, 0), 8911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds USB_REQ_GET_REPORT, 8921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds USB_TYPE_CLASS | USB_RECIP_INTERFACE | 8931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds USB_DIR_IN, (report_type << 8) + report_id, 8941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->ifnum, buffer, size, 5000); 8951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*********************************************************************** 8981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Send a command to the tablet. 8991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 9001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int 9011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsaiptek_command(struct aiptek *aiptek, unsigned char command, unsigned char data) 9021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const int sizeof_buf = 3 * sizeof(u8); 9041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret; 9051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 *buf; 9061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf = kmalloc(sizeof_buf, GFP_KERNEL); 9081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!buf) 9091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOMEM; 9101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[0] = 2; 9121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[1] = command; 9131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[2] = data; 9141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((ret = 9161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek_set_report(aiptek, 3, 2, buf, sizeof_buf)) != sizeof_buf) { 917871ba51c130d4f2e7d33b8c57e834df701357102Greg Kroah-Hartman dev_dbg(&aiptek->intf->dev, 9188fb6321b6bd9ebcc03243f27fe98e18e246a5c97Greg Kroah-Hartman "aiptek_program: failed, tried to send: 0x%02x 0x%02x\n", 9198fb6321b6bd9ebcc03243f27fe98e18e246a5c97Greg Kroah-Hartman command, data); 9201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(buf); 9221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret < 0 ? ret : 0; 9231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*********************************************************************** 9261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Retrieve information from the tablet. Querying info is defined as first 9271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * sending the {command,data} sequence as a command, followed by a wait 9281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (aka, "programmaticDelay") and then a "read" request. 9291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 9301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int 9311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsaiptek_query(struct aiptek *aiptek, unsigned char command, unsigned char data) 9321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const int sizeof_buf = 3 * sizeof(u8); 9341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret; 9351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 *buf; 9361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf = kmalloc(sizeof_buf, GFP_KERNEL); 9381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!buf) 9391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOMEM; 9401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[0] = 2; 9421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[1] = command; 9431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[2] = data; 9441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (aiptek_command(aiptek, command, data) != 0) { 9461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(buf); 9471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EIO; 9481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds msleep(aiptek->curSetting.programmableDelay); 9501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((ret = 9521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek_get_report(aiptek, 3, 2, buf, sizeof_buf)) != sizeof_buf) { 953871ba51c130d4f2e7d33b8c57e834df701357102Greg Kroah-Hartman dev_dbg(&aiptek->intf->dev, 9548fb6321b6bd9ebcc03243f27fe98e18e246a5c97Greg Kroah-Hartman "aiptek_query failed: returned 0x%02x 0x%02x 0x%02x\n", 9558fb6321b6bd9ebcc03243f27fe98e18e246a5c97Greg Kroah-Hartman buf[0], buf[1], buf[2]); 9561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = -EIO; 9571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 958858ad08cf4c32a51d26552d3cb5fa8d5e2f0e579Harvey Harrison ret = get_unaligned_le16(buf + 1); 9591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(buf); 9611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 9621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*********************************************************************** 9651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Program the tablet into either absolute or relative mode. 9661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * We also get information about the tablet's size. 9671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 9681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int aiptek_program_tablet(struct aiptek *aiptek) 9691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret; 9711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Execute Resolution500LPI */ 9721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((ret = aiptek_command(aiptek, 0x18, 0x04)) < 0) 9731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 9741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Query getModelCode */ 9761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((ret = aiptek_query(aiptek, 0x02, 0x00)) < 0) 9771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 9781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->features.modelCode = ret & 0xff; 9791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Query getODMCode */ 9811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((ret = aiptek_query(aiptek, 0x03, 0x00)) < 0) 9821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 9831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->features.odmCode = ret; 9841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Query getFirmwareCode */ 9861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((ret = aiptek_query(aiptek, 0x04, 0x00)) < 0) 9871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 9881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->features.firmwareCode = ret; 9891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Query getXextension */ 9911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((ret = aiptek_query(aiptek, 0x01, 0x00)) < 0) 9921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 993987a6c0298260b7aa40702b349282554d6180e4bDaniel Mack input_set_abs_params(aiptek->inputdev, ABS_X, 0, ret - 1, 0, 0); 9941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Query getYextension */ 9961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((ret = aiptek_query(aiptek, 0x01, 0x01)) < 0) 9971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 998987a6c0298260b7aa40702b349282554d6180e4bDaniel Mack input_set_abs_params(aiptek->inputdev, ABS_Y, 0, ret - 1, 0, 0); 9991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Query getPressureLevels */ 10011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((ret = aiptek_query(aiptek, 0x08, 0x00)) < 0) 10021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 1003987a6c0298260b7aa40702b349282554d6180e4bDaniel Mack input_set_abs_params(aiptek->inputdev, ABS_PRESSURE, 0, ret - 1, 0, 0); 10041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Depending on whether we are in absolute or relative mode, we will 10061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * do a switchToTablet(absolute) or switchToMouse(relative) command. 10071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 10081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (aiptek->curSetting.coordinateMode == 10091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds AIPTEK_COORDINATE_ABSOLUTE_MODE) { 10101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Execute switchToTablet */ 10111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((ret = aiptek_command(aiptek, 0x10, 0x01)) < 0) { 10121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 10131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 10151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Execute switchToMouse */ 10161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((ret = aiptek_command(aiptek, 0x10, 0x00)) < 0) { 10171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 10181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Enable the macro keys */ 10221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((ret = aiptek_command(aiptek, 0x11, 0x02)) < 0) 10231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 10241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if 0 10251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Execute FilterOn */ 10261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((ret = aiptek_command(aiptek, 0x17, 0x00)) < 0) 10271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 10281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 10291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Execute AutoGainOn */ 10311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((ret = aiptek_command(aiptek, 0x12, 0xff)) < 0) 10321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 10331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Reset the eventCount, so we track events from last (re)programming 10351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 10361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->diagnostic = AIPTEK_DIAGNOSTIC_NA; 10371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->eventCount = 0; 10381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 10401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*********************************************************************** 10431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Sysfs functions. Sysfs prefers that individually-tunable parameters 10441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * exist in their separate pseudo-files. Summary data that is immutable 10451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * may exist in a singular file so long as you don't define a writeable 10461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * interface. 10471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 10481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*********************************************************************** 10501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * support the 'size' file -- display support 10511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1052060b8845e6bea938d65ad6f89e83507e5ff4fec4Yani Ioannoustatic ssize_t show_tabletSize(struct device *dev, struct device_attribute *attr, char *buf) 10531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct aiptek *aiptek = dev_get_drvdata(dev); 10551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return snprintf(buf, PAGE_SIZE, "%dx%d\n", 1057987a6c0298260b7aa40702b349282554d6180e4bDaniel Mack input_abs_get_max(aiptek->inputdev, ABS_X) + 1, 1058987a6c0298260b7aa40702b349282554d6180e4bDaniel Mack input_abs_get_max(aiptek->inputdev, ABS_Y) + 1); 10591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* These structs define the sysfs files, param #1 is the name of the 10621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * file, param 2 is the file permissions, param 3 & 4 are to the 10631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * output generator and input parser routines. Absence of a routine is 10641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * permitted -- it only means can't either 'cat' the file, or send data 10651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * to it. 10661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 10671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DEVICE_ATTR(size, S_IRUGO, show_tabletSize, NULL); 10681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*********************************************************************** 10701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * support routines for the 'pointer_mode' file. Note that this file 10711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * both displays current setting and allows reprogramming. 10721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1073cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhovstatic struct aiptek_map pointer_mode_map[] = { 1074cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov { "stylus", AIPTEK_POINTER_ONLY_STYLUS_MODE }, 1075cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov { "mouse", AIPTEK_POINTER_ONLY_MOUSE_MODE }, 1076cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov { "either", AIPTEK_POINTER_EITHER_MODE }, 1077cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov { NULL, AIPTEK_INVALID_VALUE } 1078cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov}; 1079cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov 1080060b8845e6bea938d65ad6f89e83507e5ff4fec4Yani Ioannoustatic ssize_t show_tabletPointerMode(struct device *dev, struct device_attribute *attr, char *buf) 10811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct aiptek *aiptek = dev_get_drvdata(dev); 10831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1084cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov return snprintf(buf, PAGE_SIZE, "%s\n", 1085cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov map_val_to_str(pointer_mode_map, 1086cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov aiptek->curSetting.pointerMode)); 10871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t 1090060b8845e6bea938d65ad6f89e83507e5ff4fec4Yani Ioannoustore_tabletPointerMode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 10911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct aiptek *aiptek = dev_get_drvdata(dev); 1093cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov int new_mode = map_str_to_val(pointer_mode_map, buf, count); 10941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1095cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov if (new_mode == AIPTEK_INVALID_VALUE) 1096cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov return -EINVAL; 1097cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov 1098cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov aiptek->newSetting.pointerMode = new_mode; 10991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 11001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 11011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DEVICE_ATTR(pointer_mode, 11036f07d31e46639e4b1b23de6ee88c9e079a7bf32dDmitry Torokhov S_IRUGO | S_IWUSR, 11041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds show_tabletPointerMode, store_tabletPointerMode); 11051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*********************************************************************** 11071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * support routines for the 'coordinate_mode' file. Note that this file 11081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * both displays current setting and allows reprogramming. 11091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1110cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov 1111cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhovstatic struct aiptek_map coordinate_mode_map[] = { 1112cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov { "absolute", AIPTEK_COORDINATE_ABSOLUTE_MODE }, 1113cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov { "relative", AIPTEK_COORDINATE_RELATIVE_MODE }, 1114cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov { NULL, AIPTEK_INVALID_VALUE } 1115cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov}; 1116cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov 1117060b8845e6bea938d65ad6f89e83507e5ff4fec4Yani Ioannoustatic ssize_t show_tabletCoordinateMode(struct device *dev, struct device_attribute *attr, char *buf) 11181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 11191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct aiptek *aiptek = dev_get_drvdata(dev); 11201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1121cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov return snprintf(buf, PAGE_SIZE, "%s\n", 1122cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov map_val_to_str(coordinate_mode_map, 1123cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov aiptek->curSetting.coordinateMode)); 11241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 11251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t 1127060b8845e6bea938d65ad6f89e83507e5ff4fec4Yani Ioannoustore_tabletCoordinateMode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 11281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 11291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct aiptek *aiptek = dev_get_drvdata(dev); 1130cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov int new_mode = map_str_to_val(coordinate_mode_map, buf, count); 11311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1132cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov if (new_mode == AIPTEK_INVALID_VALUE) 1133cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov return -EINVAL; 1134cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov 1135cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov aiptek->newSetting.coordinateMode = new_mode; 11361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 11371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 11381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DEVICE_ATTR(coordinate_mode, 11406f07d31e46639e4b1b23de6ee88c9e079a7bf32dDmitry Torokhov S_IRUGO | S_IWUSR, 11411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds show_tabletCoordinateMode, store_tabletCoordinateMode); 11421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*********************************************************************** 11441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * support routines for the 'tool_mode' file. Note that this file 11451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * both displays current setting and allows reprogramming. 11461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1147cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov 1148cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhovstatic struct aiptek_map tool_mode_map[] = { 1149cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov { "mouse", AIPTEK_TOOL_BUTTON_MOUSE_MODE }, 1150cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov { "eraser", AIPTEK_TOOL_BUTTON_ERASER_MODE }, 1151cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov { "pencil", AIPTEK_TOOL_BUTTON_PENCIL_MODE }, 1152cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov { "pen", AIPTEK_TOOL_BUTTON_PEN_MODE }, 1153cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov { "brush", AIPTEK_TOOL_BUTTON_BRUSH_MODE }, 1154cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov { "airbrush", AIPTEK_TOOL_BUTTON_AIRBRUSH_MODE }, 1155cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov { "lens", AIPTEK_TOOL_BUTTON_LENS_MODE }, 1156cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov { NULL, AIPTEK_INVALID_VALUE } 1157cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov}; 1158cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov 1159060b8845e6bea938d65ad6f89e83507e5ff4fec4Yani Ioannoustatic ssize_t show_tabletToolMode(struct device *dev, struct device_attribute *attr, char *buf) 11601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 11611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct aiptek *aiptek = dev_get_drvdata(dev); 11621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1163cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov return snprintf(buf, PAGE_SIZE, "%s\n", 1164cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov map_val_to_str(tool_mode_map, 1165cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov aiptek->curSetting.toolMode)); 11661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 11671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t 1169060b8845e6bea938d65ad6f89e83507e5ff4fec4Yani Ioannoustore_tabletToolMode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 11701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 11711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct aiptek *aiptek = dev_get_drvdata(dev); 1172cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov int new_mode = map_str_to_val(tool_mode_map, buf, count); 11731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1174cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov if (new_mode == AIPTEK_INVALID_VALUE) 1175cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov return -EINVAL; 11761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1177cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov aiptek->newSetting.toolMode = new_mode; 11781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 11791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 11801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DEVICE_ATTR(tool_mode, 11826f07d31e46639e4b1b23de6ee88c9e079a7bf32dDmitry Torokhov S_IRUGO | S_IWUSR, 11831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds show_tabletToolMode, store_tabletToolMode); 11841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*********************************************************************** 11861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * support routines for the 'xtilt' file. Note that this file 11871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * both displays current setting and allows reprogramming. 11881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1189060b8845e6bea938d65ad6f89e83507e5ff4fec4Yani Ioannoustatic ssize_t show_tabletXtilt(struct device *dev, struct device_attribute *attr, char *buf) 11901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 11911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct aiptek *aiptek = dev_get_drvdata(dev); 11921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (aiptek->curSetting.xTilt == AIPTEK_TILT_DISABLE) { 11941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return snprintf(buf, PAGE_SIZE, "disable\n"); 11951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 11961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return snprintf(buf, PAGE_SIZE, "%d\n", 11971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->curSetting.xTilt); 11981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 12001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t 1202060b8845e6bea938d65ad6f89e83507e5ff4fec4Yani Ioannoustore_tabletXtilt(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 12031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 12041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct aiptek *aiptek = dev_get_drvdata(dev); 120576496e7a02e99d42844f4fffa145b81e513e7acdJJ Ding int x; 1206160f1fef7e52e974489b3c70fbd4e094c06965c2Joe Rouvier 120776496e7a02e99d42844f4fffa145b81e513e7acdJJ Ding if (kstrtoint(buf, 10, &x)) { 1208160f1fef7e52e974489b3c70fbd4e094c06965c2Joe Rouvier size_t len = buf[count - 1] == '\n' ? count - 1 : count; 1209160f1fef7e52e974489b3c70fbd4e094c06965c2Joe Rouvier 1210160f1fef7e52e974489b3c70fbd4e094c06965c2Joe Rouvier if (strncmp(buf, "disable", len)) 1211160f1fef7e52e974489b3c70fbd4e094c06965c2Joe Rouvier return -EINVAL; 12121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->newSetting.xTilt = AIPTEK_TILT_DISABLE; 12141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 1215160f1fef7e52e974489b3c70fbd4e094c06965c2Joe Rouvier if (x < AIPTEK_TILT_MIN || x > AIPTEK_TILT_MAX) 1216160f1fef7e52e974489b3c70fbd4e094c06965c2Joe Rouvier return -EINVAL; 1217160f1fef7e52e974489b3c70fbd4e094c06965c2Joe Rouvier 1218160f1fef7e52e974489b3c70fbd4e094c06965c2Joe Rouvier aiptek->newSetting.xTilt = x; 12191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1220160f1fef7e52e974489b3c70fbd4e094c06965c2Joe Rouvier 12211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 12221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 12231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DEVICE_ATTR(xtilt, 12256f07d31e46639e4b1b23de6ee88c9e079a7bf32dDmitry Torokhov S_IRUGO | S_IWUSR, show_tabletXtilt, store_tabletXtilt); 12261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*********************************************************************** 12281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * support routines for the 'ytilt' file. Note that this file 12291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * both displays current setting and allows reprogramming. 12301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1231060b8845e6bea938d65ad6f89e83507e5ff4fec4Yani Ioannoustatic ssize_t show_tabletYtilt(struct device *dev, struct device_attribute *attr, char *buf) 12321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 12331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct aiptek *aiptek = dev_get_drvdata(dev); 12341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (aiptek->curSetting.yTilt == AIPTEK_TILT_DISABLE) { 12361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return snprintf(buf, PAGE_SIZE, "disable\n"); 12371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 12381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return snprintf(buf, PAGE_SIZE, "%d\n", 12391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->curSetting.yTilt); 12401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 12421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t 1244060b8845e6bea938d65ad6f89e83507e5ff4fec4Yani Ioannoustore_tabletYtilt(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 12451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 12461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct aiptek *aiptek = dev_get_drvdata(dev); 124776496e7a02e99d42844f4fffa145b81e513e7acdJJ Ding int y; 1248160f1fef7e52e974489b3c70fbd4e094c06965c2Joe Rouvier 124976496e7a02e99d42844f4fffa145b81e513e7acdJJ Ding if (kstrtoint(buf, 10, &y)) { 1250160f1fef7e52e974489b3c70fbd4e094c06965c2Joe Rouvier size_t len = buf[count - 1] == '\n' ? count - 1 : count; 1251160f1fef7e52e974489b3c70fbd4e094c06965c2Joe Rouvier 1252160f1fef7e52e974489b3c70fbd4e094c06965c2Joe Rouvier if (strncmp(buf, "disable", len)) 1253160f1fef7e52e974489b3c70fbd4e094c06965c2Joe Rouvier return -EINVAL; 12541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->newSetting.yTilt = AIPTEK_TILT_DISABLE; 12561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 1257160f1fef7e52e974489b3c70fbd4e094c06965c2Joe Rouvier if (y < AIPTEK_TILT_MIN || y > AIPTEK_TILT_MAX) 1258160f1fef7e52e974489b3c70fbd4e094c06965c2Joe Rouvier return -EINVAL; 1259160f1fef7e52e974489b3c70fbd4e094c06965c2Joe Rouvier 1260160f1fef7e52e974489b3c70fbd4e094c06965c2Joe Rouvier aiptek->newSetting.yTilt = y; 12611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1262160f1fef7e52e974489b3c70fbd4e094c06965c2Joe Rouvier 12631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 12641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 12651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DEVICE_ATTR(ytilt, 12676f07d31e46639e4b1b23de6ee88c9e079a7bf32dDmitry Torokhov S_IRUGO | S_IWUSR, show_tabletYtilt, store_tabletYtilt); 12681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*********************************************************************** 12701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * support routines for the 'jitter' file. Note that this file 12711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * both displays current setting and allows reprogramming. 12721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1273060b8845e6bea938d65ad6f89e83507e5ff4fec4Yani Ioannoustatic ssize_t show_tabletJitterDelay(struct device *dev, struct device_attribute *attr, char *buf) 12741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 12751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct aiptek *aiptek = dev_get_drvdata(dev); 12761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return snprintf(buf, PAGE_SIZE, "%d\n", aiptek->curSetting.jitterDelay); 12781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 12791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t 1281060b8845e6bea938d65ad6f89e83507e5ff4fec4Yani Ioannoustore_tabletJitterDelay(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 12821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 12831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct aiptek *aiptek = dev_get_drvdata(dev); 128476496e7a02e99d42844f4fffa145b81e513e7acdJJ Ding int err, j; 1285160f1fef7e52e974489b3c70fbd4e094c06965c2Joe Rouvier 128676496e7a02e99d42844f4fffa145b81e513e7acdJJ Ding err = kstrtoint(buf, 10, &j); 128776496e7a02e99d42844f4fffa145b81e513e7acdJJ Ding if (err) 128876496e7a02e99d42844f4fffa145b81e513e7acdJJ Ding return err; 12891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 129076496e7a02e99d42844f4fffa145b81e513e7acdJJ Ding aiptek->newSetting.jitterDelay = j; 12911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 12921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 12931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DEVICE_ATTR(jitter, 12956f07d31e46639e4b1b23de6ee88c9e079a7bf32dDmitry Torokhov S_IRUGO | S_IWUSR, 12961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds show_tabletJitterDelay, store_tabletJitterDelay); 12971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*********************************************************************** 12991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * support routines for the 'delay' file. Note that this file 13001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * both displays current setting and allows reprogramming. 13011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1302060b8845e6bea938d65ad6f89e83507e5ff4fec4Yani Ioannoustatic ssize_t show_tabletProgrammableDelay(struct device *dev, struct device_attribute *attr, char *buf) 13031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 13041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct aiptek *aiptek = dev_get_drvdata(dev); 13051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return snprintf(buf, PAGE_SIZE, "%d\n", 13071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->curSetting.programmableDelay); 13081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 13091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t 1311060b8845e6bea938d65ad6f89e83507e5ff4fec4Yani Ioannoustore_tabletProgrammableDelay(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 13121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 13131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct aiptek *aiptek = dev_get_drvdata(dev); 131476496e7a02e99d42844f4fffa145b81e513e7acdJJ Ding int err, d; 13151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 131676496e7a02e99d42844f4fffa145b81e513e7acdJJ Ding err = kstrtoint(buf, 10, &d); 131776496e7a02e99d42844f4fffa145b81e513e7acdJJ Ding if (err) 131876496e7a02e99d42844f4fffa145b81e513e7acdJJ Ding return err; 1319160f1fef7e52e974489b3c70fbd4e094c06965c2Joe Rouvier 132076496e7a02e99d42844f4fffa145b81e513e7acdJJ Ding aiptek->newSetting.programmableDelay = d; 13211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 13221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 13231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DEVICE_ATTR(delay, 13256f07d31e46639e4b1b23de6ee88c9e079a7bf32dDmitry Torokhov S_IRUGO | S_IWUSR, 13261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds show_tabletProgrammableDelay, store_tabletProgrammableDelay); 13271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*********************************************************************** 13291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * support routines for the 'event_count' file. Note that this file 13301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * only displays current setting. 13311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1332060b8845e6bea938d65ad6f89e83507e5ff4fec4Yani Ioannoustatic ssize_t show_tabletEventsReceived(struct device *dev, struct device_attribute *attr, char *buf) 13331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 13341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct aiptek *aiptek = dev_get_drvdata(dev); 13351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return snprintf(buf, PAGE_SIZE, "%ld\n", aiptek->eventCount); 13371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 13381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DEVICE_ATTR(event_count, S_IRUGO, show_tabletEventsReceived, NULL); 13401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*********************************************************************** 13421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * support routines for the 'diagnostic' file. Note that this file 13431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * only displays current setting. 13441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1345060b8845e6bea938d65ad6f89e83507e5ff4fec4Yani Ioannoustatic ssize_t show_tabletDiagnosticMessage(struct device *dev, struct device_attribute *attr, char *buf) 13461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 13471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct aiptek *aiptek = dev_get_drvdata(dev); 13481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char *retMsg; 13491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (aiptek->diagnostic) { 13511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AIPTEK_DIAGNOSTIC_NA: 13521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retMsg = "no errors\n"; 13531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AIPTEK_DIAGNOSTIC_SENDING_RELATIVE_IN_ABSOLUTE: 13561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retMsg = "Error: receiving relative reports\n"; 13571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AIPTEK_DIAGNOSTIC_SENDING_ABSOLUTE_IN_RELATIVE: 13601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retMsg = "Error: receiving absolute reports\n"; 13611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AIPTEK_DIAGNOSTIC_TOOL_DISALLOWED: 13641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (aiptek->curSetting.pointerMode == 13651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds AIPTEK_POINTER_ONLY_MOUSE_MODE) { 13661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retMsg = "Error: receiving stylus reports\n"; 13671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 13681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retMsg = "Error: receiving mouse reports\n"; 13691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 13711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 13731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 13741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return snprintf(buf, PAGE_SIZE, retMsg); 13761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 13771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DEVICE_ATTR(diagnostic, S_IRUGO, show_tabletDiagnosticMessage, NULL); 13791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*********************************************************************** 13811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * support routines for the 'stylus_upper' file. Note that this file 13821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * both displays current setting and allows for setting changing. 13831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1384cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov 1385cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhovstatic struct aiptek_map stylus_button_map[] = { 1386cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov { "upper", AIPTEK_STYLUS_UPPER_BUTTON }, 1387cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov { "lower", AIPTEK_STYLUS_LOWER_BUTTON }, 1388cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov { NULL, AIPTEK_INVALID_VALUE } 1389cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov}; 1390cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov 1391060b8845e6bea938d65ad6f89e83507e5ff4fec4Yani Ioannoustatic ssize_t show_tabletStylusUpper(struct device *dev, struct device_attribute *attr, char *buf) 13921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 13931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct aiptek *aiptek = dev_get_drvdata(dev); 13941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1395cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov return snprintf(buf, PAGE_SIZE, "%s\n", 1396cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov map_val_to_str(stylus_button_map, 1397cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov aiptek->curSetting.stylusButtonUpper)); 13981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 13991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t 1401060b8845e6bea938d65ad6f89e83507e5ff4fec4Yani Ioannoustore_tabletStylusUpper(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 14021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 14031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct aiptek *aiptek = dev_get_drvdata(dev); 1404cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov int new_button = map_str_to_val(stylus_button_map, buf, count); 14051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1406cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov if (new_button == AIPTEK_INVALID_VALUE) 1407cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov return -EINVAL; 1408cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov 1409cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov aiptek->newSetting.stylusButtonUpper = new_button; 14101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 14111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DEVICE_ATTR(stylus_upper, 14146f07d31e46639e4b1b23de6ee88c9e079a7bf32dDmitry Torokhov S_IRUGO | S_IWUSR, 14151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds show_tabletStylusUpper, store_tabletStylusUpper); 14161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*********************************************************************** 14181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * support routines for the 'stylus_lower' file. Note that this file 14191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * both displays current setting and allows for setting changing. 14201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1421cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov 1422060b8845e6bea938d65ad6f89e83507e5ff4fec4Yani Ioannoustatic ssize_t show_tabletStylusLower(struct device *dev, struct device_attribute *attr, char *buf) 14231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 14241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct aiptek *aiptek = dev_get_drvdata(dev); 14251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1426cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov return snprintf(buf, PAGE_SIZE, "%s\n", 1427cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov map_val_to_str(stylus_button_map, 1428cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov aiptek->curSetting.stylusButtonLower)); 14291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t 1432060b8845e6bea938d65ad6f89e83507e5ff4fec4Yani Ioannoustore_tabletStylusLower(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 14331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 14341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct aiptek *aiptek = dev_get_drvdata(dev); 1435cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov int new_button = map_str_to_val(stylus_button_map, buf, count); 14361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1437cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov if (new_button == AIPTEK_INVALID_VALUE) 1438cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov return -EINVAL; 1439cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov 1440cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov aiptek->newSetting.stylusButtonLower = new_button; 14411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 14421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DEVICE_ATTR(stylus_lower, 14456f07d31e46639e4b1b23de6ee88c9e079a7bf32dDmitry Torokhov S_IRUGO | S_IWUSR, 14461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds show_tabletStylusLower, store_tabletStylusLower); 14471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*********************************************************************** 14491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * support routines for the 'mouse_left' file. Note that this file 14501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * both displays current setting and allows for setting changing. 14511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1452cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov 1453cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhovstatic struct aiptek_map mouse_button_map[] = { 1454cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov { "left", AIPTEK_MOUSE_LEFT_BUTTON }, 1455cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov { "middle", AIPTEK_MOUSE_MIDDLE_BUTTON }, 1456cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov { "right", AIPTEK_MOUSE_RIGHT_BUTTON }, 1457cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov { NULL, AIPTEK_INVALID_VALUE } 1458cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov}; 1459cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov 1460060b8845e6bea938d65ad6f89e83507e5ff4fec4Yani Ioannoustatic ssize_t show_tabletMouseLeft(struct device *dev, struct device_attribute *attr, char *buf) 14611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 14621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct aiptek *aiptek = dev_get_drvdata(dev); 14631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1464cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov return snprintf(buf, PAGE_SIZE, "%s\n", 1465cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov map_val_to_str(mouse_button_map, 1466cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov aiptek->curSetting.mouseButtonLeft)); 14671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t 1470060b8845e6bea938d65ad6f89e83507e5ff4fec4Yani Ioannoustore_tabletMouseLeft(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 14711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 14721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct aiptek *aiptek = dev_get_drvdata(dev); 1473cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov int new_button = map_str_to_val(mouse_button_map, buf, count); 14741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1475cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov if (new_button == AIPTEK_INVALID_VALUE) 1476cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov return -EINVAL; 1477cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov 1478cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov aiptek->newSetting.mouseButtonLeft = new_button; 14791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 14801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DEVICE_ATTR(mouse_left, 14836f07d31e46639e4b1b23de6ee88c9e079a7bf32dDmitry Torokhov S_IRUGO | S_IWUSR, 14841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds show_tabletMouseLeft, store_tabletMouseLeft); 14851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*********************************************************************** 14871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * support routines for the 'mouse_middle' file. Note that this file 14881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * both displays current setting and allows for setting changing. 14891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1490060b8845e6bea938d65ad6f89e83507e5ff4fec4Yani Ioannoustatic ssize_t show_tabletMouseMiddle(struct device *dev, struct device_attribute *attr, char *buf) 14911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 14921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct aiptek *aiptek = dev_get_drvdata(dev); 14931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1494cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov return snprintf(buf, PAGE_SIZE, "%s\n", 1495cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov map_val_to_str(mouse_button_map, 1496cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov aiptek->curSetting.mouseButtonMiddle)); 14971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t 1500060b8845e6bea938d65ad6f89e83507e5ff4fec4Yani Ioannoustore_tabletMouseMiddle(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 15011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 15021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct aiptek *aiptek = dev_get_drvdata(dev); 1503cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov int new_button = map_str_to_val(mouse_button_map, buf, count); 15041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1505cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov if (new_button == AIPTEK_INVALID_VALUE) 1506cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov return -EINVAL; 1507cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov 1508cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov aiptek->newSetting.mouseButtonMiddle = new_button; 15091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 15101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 15111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DEVICE_ATTR(mouse_middle, 15136f07d31e46639e4b1b23de6ee88c9e079a7bf32dDmitry Torokhov S_IRUGO | S_IWUSR, 15141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds show_tabletMouseMiddle, store_tabletMouseMiddle); 15151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*********************************************************************** 15171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * support routines for the 'mouse_right' file. Note that this file 15181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * both displays current setting and allows for setting changing. 15191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1520060b8845e6bea938d65ad6f89e83507e5ff4fec4Yani Ioannoustatic ssize_t show_tabletMouseRight(struct device *dev, struct device_attribute *attr, char *buf) 15211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 15221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct aiptek *aiptek = dev_get_drvdata(dev); 15231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1524cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov return snprintf(buf, PAGE_SIZE, "%s\n", 1525cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov map_val_to_str(mouse_button_map, 1526cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov aiptek->curSetting.mouseButtonRight)); 15271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 15281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t 1530060b8845e6bea938d65ad6f89e83507e5ff4fec4Yani Ioannoustore_tabletMouseRight(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 15311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 15321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct aiptek *aiptek = dev_get_drvdata(dev); 1533cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov int new_button = map_str_to_val(mouse_button_map, buf, count); 15341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1535cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov if (new_button == AIPTEK_INVALID_VALUE) 1536cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov return -EINVAL; 1537cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov 1538cd438a58c89221d8642455d0cc8ec96d3b822f6eDmitry Torokhov aiptek->newSetting.mouseButtonRight = new_button; 15391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 15401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 15411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DEVICE_ATTR(mouse_right, 15436f07d31e46639e4b1b23de6ee88c9e079a7bf32dDmitry Torokhov S_IRUGO | S_IWUSR, 15441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds show_tabletMouseRight, store_tabletMouseRight); 15451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*********************************************************************** 15471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * support routines for the 'wheel' file. Note that this file 15481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * both displays current setting and allows for setting changing. 15491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1550060b8845e6bea938d65ad6f89e83507e5ff4fec4Yani Ioannoustatic ssize_t show_tabletWheel(struct device *dev, struct device_attribute *attr, char *buf) 15511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 15521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct aiptek *aiptek = dev_get_drvdata(dev); 15531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (aiptek->curSetting.wheel == AIPTEK_WHEEL_DISABLE) { 15551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return snprintf(buf, PAGE_SIZE, "disable\n"); 15561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 15571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return snprintf(buf, PAGE_SIZE, "%d\n", 15581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->curSetting.wheel); 15591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 15601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 15611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t 1563060b8845e6bea938d65ad6f89e83507e5ff4fec4Yani Ioannoustore_tabletWheel(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 15641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 15651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct aiptek *aiptek = dev_get_drvdata(dev); 156676496e7a02e99d42844f4fffa145b81e513e7acdJJ Ding int err, w; 1567160f1fef7e52e974489b3c70fbd4e094c06965c2Joe Rouvier 156876496e7a02e99d42844f4fffa145b81e513e7acdJJ Ding err = kstrtoint(buf, 10, &w); 156976496e7a02e99d42844f4fffa145b81e513e7acdJJ Ding if (err) 157076496e7a02e99d42844f4fffa145b81e513e7acdJJ Ding return err; 15711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 157276496e7a02e99d42844f4fffa145b81e513e7acdJJ Ding aiptek->newSetting.wheel = w; 15731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 15741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 15751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DEVICE_ATTR(wheel, 15776f07d31e46639e4b1b23de6ee88c9e079a7bf32dDmitry Torokhov S_IRUGO | S_IWUSR, show_tabletWheel, store_tabletWheel); 15781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*********************************************************************** 15801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * support routines for the 'execute' file. Note that this file 15811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * both displays current setting and allows for setting changing. 15821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1583060b8845e6bea938d65ad6f89e83507e5ff4fec4Yani Ioannoustatic ssize_t show_tabletExecute(struct device *dev, struct device_attribute *attr, char *buf) 15841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 15851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* There is nothing useful to display, so a one-line manual 15861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * is in order... 15871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 15881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return snprintf(buf, PAGE_SIZE, 15891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "Write anything to this file to program your tablet.\n"); 15901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 15911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t 1593060b8845e6bea938d65ad6f89e83507e5ff4fec4Yani Ioannoustore_tabletExecute(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 15941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 15951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct aiptek *aiptek = dev_get_drvdata(dev); 15961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* We do not care what you write to this file. Merely the action 15981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * of writing to this file triggers a tablet reprogramming. 15991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 16001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(&aiptek->curSetting, &aiptek->newSetting, 16011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sizeof(struct aiptek_settings)); 16021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (aiptek_program_tablet(aiptek) < 0) 16041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EIO; 16051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 16071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 16081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DEVICE_ATTR(execute, 16106f07d31e46639e4b1b23de6ee88c9e079a7bf32dDmitry Torokhov S_IRUGO | S_IWUSR, show_tabletExecute, store_tabletExecute); 16111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*********************************************************************** 16131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * support routines for the 'odm_code' file. Note that this file 16141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * only displays current setting. 16151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1616060b8845e6bea938d65ad6f89e83507e5ff4fec4Yani Ioannoustatic ssize_t show_tabletODMCode(struct device *dev, struct device_attribute *attr, char *buf) 16171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 16181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct aiptek *aiptek = dev_get_drvdata(dev); 16191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return snprintf(buf, PAGE_SIZE, "0x%04x\n", aiptek->features.odmCode); 16211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 16221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DEVICE_ATTR(odm_code, S_IRUGO, show_tabletODMCode, NULL); 16241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*********************************************************************** 16261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * support routines for the 'model_code' file. Note that this file 16271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * only displays current setting. 16281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1629060b8845e6bea938d65ad6f89e83507e5ff4fec4Yani Ioannoustatic ssize_t show_tabletModelCode(struct device *dev, struct device_attribute *attr, char *buf) 16301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 16311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct aiptek *aiptek = dev_get_drvdata(dev); 16321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return snprintf(buf, PAGE_SIZE, "0x%04x\n", aiptek->features.modelCode); 16341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 16351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DEVICE_ATTR(model_code, S_IRUGO, show_tabletModelCode, NULL); 16371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*********************************************************************** 16391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * support routines for the 'firmware_code' file. Note that this file 16401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * only displays current setting. 16411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1642060b8845e6bea938d65ad6f89e83507e5ff4fec4Yani Ioannoustatic ssize_t show_firmwareCode(struct device *dev, struct device_attribute *attr, char *buf) 16431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 16441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct aiptek *aiptek = dev_get_drvdata(dev); 16451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return snprintf(buf, PAGE_SIZE, "%04x\n", 16471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->features.firmwareCode); 16481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 16491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DEVICE_ATTR(firmware_code, S_IRUGO, show_firmwareCode, NULL); 16511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1652b087e1f3ee9ae4da49fdeca2b0f0f8fc5a886a79Dmitry Torokhovstatic struct attribute *aiptek_attributes[] = { 1653b087e1f3ee9ae4da49fdeca2b0f0f8fc5a886a79Dmitry Torokhov &dev_attr_size.attr, 1654b087e1f3ee9ae4da49fdeca2b0f0f8fc5a886a79Dmitry Torokhov &dev_attr_pointer_mode.attr, 1655b087e1f3ee9ae4da49fdeca2b0f0f8fc5a886a79Dmitry Torokhov &dev_attr_coordinate_mode.attr, 1656b087e1f3ee9ae4da49fdeca2b0f0f8fc5a886a79Dmitry Torokhov &dev_attr_tool_mode.attr, 1657b087e1f3ee9ae4da49fdeca2b0f0f8fc5a886a79Dmitry Torokhov &dev_attr_xtilt.attr, 1658b087e1f3ee9ae4da49fdeca2b0f0f8fc5a886a79Dmitry Torokhov &dev_attr_ytilt.attr, 1659b087e1f3ee9ae4da49fdeca2b0f0f8fc5a886a79Dmitry Torokhov &dev_attr_jitter.attr, 1660b087e1f3ee9ae4da49fdeca2b0f0f8fc5a886a79Dmitry Torokhov &dev_attr_delay.attr, 1661b087e1f3ee9ae4da49fdeca2b0f0f8fc5a886a79Dmitry Torokhov &dev_attr_event_count.attr, 1662b087e1f3ee9ae4da49fdeca2b0f0f8fc5a886a79Dmitry Torokhov &dev_attr_diagnostic.attr, 1663b087e1f3ee9ae4da49fdeca2b0f0f8fc5a886a79Dmitry Torokhov &dev_attr_odm_code.attr, 1664b087e1f3ee9ae4da49fdeca2b0f0f8fc5a886a79Dmitry Torokhov &dev_attr_model_code.attr, 1665b087e1f3ee9ae4da49fdeca2b0f0f8fc5a886a79Dmitry Torokhov &dev_attr_firmware_code.attr, 1666b087e1f3ee9ae4da49fdeca2b0f0f8fc5a886a79Dmitry Torokhov &dev_attr_stylus_lower.attr, 1667b087e1f3ee9ae4da49fdeca2b0f0f8fc5a886a79Dmitry Torokhov &dev_attr_stylus_upper.attr, 1668b087e1f3ee9ae4da49fdeca2b0f0f8fc5a886a79Dmitry Torokhov &dev_attr_mouse_left.attr, 1669b087e1f3ee9ae4da49fdeca2b0f0f8fc5a886a79Dmitry Torokhov &dev_attr_mouse_middle.attr, 1670b087e1f3ee9ae4da49fdeca2b0f0f8fc5a886a79Dmitry Torokhov &dev_attr_mouse_right.attr, 1671b087e1f3ee9ae4da49fdeca2b0f0f8fc5a886a79Dmitry Torokhov &dev_attr_wheel.attr, 1672b087e1f3ee9ae4da49fdeca2b0f0f8fc5a886a79Dmitry Torokhov &dev_attr_execute.attr, 1673b087e1f3ee9ae4da49fdeca2b0f0f8fc5a886a79Dmitry Torokhov NULL 1674b087e1f3ee9ae4da49fdeca2b0f0f8fc5a886a79Dmitry Torokhov}; 16751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1676b087e1f3ee9ae4da49fdeca2b0f0f8fc5a886a79Dmitry Torokhovstatic struct attribute_group aiptek_attribute_group = { 1677b087e1f3ee9ae4da49fdeca2b0f0f8fc5a886a79Dmitry Torokhov .attrs = aiptek_attributes, 1678b087e1f3ee9ae4da49fdeca2b0f0f8fc5a886a79Dmitry Torokhov}; 16791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*********************************************************************** 16811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This routine is called when a tablet has been identified. It basically 16821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * sets up the tablet and the driver's internal structures. 16831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 16841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int 16851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsaiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) 16861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 16871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct usb_device *usbdev = interface_to_usbdev(intf); 16881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct usb_endpoint_descriptor *endpoint; 16891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct aiptek *aiptek; 16901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct input_dev *inputdev; 16911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 16921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int speeds[] = { 0, 16931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds AIPTEK_PROGRAMMABLE_DELAY_50, 16941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds AIPTEK_PROGRAMMABLE_DELAY_400, 16951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds AIPTEK_PROGRAMMABLE_DELAY_25, 16961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds AIPTEK_PROGRAMMABLE_DELAY_100, 16971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds AIPTEK_PROGRAMMABLE_DELAY_200, 16981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds AIPTEK_PROGRAMMABLE_DELAY_300 16991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds }; 17005014186de89708d0e9eed60526b698d5b786b707Dmitry Torokhov int err = -ENOMEM; 17011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* programmableDelay is where the command-line specified 17031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * delay is kept. We make it the first element of speeds[], 17041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * so therefore, your override speed is tried first, then the 17051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * remainder. Note that the default value of 400ms will be tried 17061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * if you do not specify any command line parameter. 17071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 17081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds speeds[0] = programmableDelay; 17091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1710c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov aiptek = kzalloc(sizeof(struct aiptek), GFP_KERNEL); 1711c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov inputdev = input_allocate_device(); 17126125a400354c4a02b9dad0e5d8128f9dc08cfd51Rene van Paassen if (!aiptek || !inputdev) { 17131817b1692a2eab022e805d32e910f4556c89dce8Greg Kroah-Hartman dev_warn(&intf->dev, 17141817b1692a2eab022e805d32e910f4556c89dce8Greg Kroah-Hartman "cannot allocate memory or input device\n"); 1715c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov goto fail1; 17166125a400354c4a02b9dad0e5d8128f9dc08cfd51Rene van Paassen } 17171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1718997ea58eb92f9970b8af7aae48800d0ef43b9423Daniel Mack aiptek->data = usb_alloc_coherent(usbdev, AIPTEK_PACKET_LENGTH, 1719997ea58eb92f9970b8af7aae48800d0ef43b9423Daniel Mack GFP_ATOMIC, &aiptek->data_dma); 17206125a400354c4a02b9dad0e5d8128f9dc08cfd51Rene van Paassen if (!aiptek->data) { 17211817b1692a2eab022e805d32e910f4556c89dce8Greg Kroah-Hartman dev_warn(&intf->dev, "cannot allocate usb buffer\n"); 1722c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov goto fail1; 17236125a400354c4a02b9dad0e5d8128f9dc08cfd51Rene van Paassen } 17241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->urb = usb_alloc_urb(0, GFP_KERNEL); 17266125a400354c4a02b9dad0e5d8128f9dc08cfd51Rene van Paassen if (!aiptek->urb) { 17271817b1692a2eab022e805d32e910f4556c89dce8Greg Kroah-Hartman dev_warn(&intf->dev, "cannot allocate urb\n"); 1728c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov goto fail2; 17296125a400354c4a02b9dad0e5d8128f9dc08cfd51Rene van Paassen } 1730c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov 1731c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov aiptek->inputdev = inputdev; 1732c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov aiptek->usbdev = usbdev; 1733871ba51c130d4f2e7d33b8c57e834df701357102Greg Kroah-Hartman aiptek->intf = intf; 1734c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov aiptek->ifnum = intf->altsetting[0].desc.bInterfaceNumber; 1735c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov aiptek->inDelay = 0; 1736c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov aiptek->endDelay = 0; 1737c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov aiptek->previousJitterable = 0; 17381e7b3faed1793e7637a774240ae22541c5ba6ca0Rene van Paassen aiptek->lastMacro = -1; 17391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Set up the curSettings struct. Said struct contains the current 17411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * programmable parameters. The newSetting struct contains changes 17421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the user makes to the settings via the sysfs interface. Those 17431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * changes are not "committed" to curSettings until the user 17441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * writes to the sysfs/.../execute file. 17451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 17461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->curSetting.pointerMode = AIPTEK_POINTER_EITHER_MODE; 17471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->curSetting.coordinateMode = AIPTEK_COORDINATE_ABSOLUTE_MODE; 17481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->curSetting.toolMode = AIPTEK_TOOL_BUTTON_PEN_MODE; 17491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->curSetting.xTilt = AIPTEK_TILT_DISABLE; 17501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->curSetting.yTilt = AIPTEK_TILT_DISABLE; 17511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->curSetting.mouseButtonLeft = AIPTEK_MOUSE_LEFT_BUTTON; 17521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->curSetting.mouseButtonMiddle = AIPTEK_MOUSE_MIDDLE_BUTTON; 17531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->curSetting.mouseButtonRight = AIPTEK_MOUSE_RIGHT_BUTTON; 17541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->curSetting.stylusButtonUpper = AIPTEK_STYLUS_UPPER_BUTTON; 17551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->curSetting.stylusButtonLower = AIPTEK_STYLUS_LOWER_BUTTON; 17561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->curSetting.jitterDelay = jitterDelay; 17571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->curSetting.programmableDelay = programmableDelay; 17581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Both structs should have equivalent settings 17601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1761c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov aiptek->newSetting = aiptek->curSetting; 1762c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov 1763c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov /* Determine the usb devices' physical path. 1764c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov * Asketh not why we always pretend we're using "../input0", 1765c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov * but I suspect this will have to be refactored one 1766c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov * day if a single USB device can be a keyboard & a mouse 1767c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov * & a tablet, and the inputX number actually will tell 1768c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov * us something... 1769c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov */ 1770c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov usb_make_path(usbdev, aiptek->features.usbPath, 1771c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov sizeof(aiptek->features.usbPath)); 1772c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov strlcat(aiptek->features.usbPath, "/input0", 1773c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov sizeof(aiptek->features.usbPath)); 1774c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov 1775c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov /* Set up client data, pointers to open and close routines 1776c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov * for the input device. 1777c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov */ 1778c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov inputdev->name = "Aiptek"; 1779c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov inputdev->phys = aiptek->features.usbPath; 1780c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov usb_to_input_id(usbdev, &inputdev->id); 1781c0f82d570c84f2592367e350a92ebd71e72ba68aDmitry Torokhov inputdev->dev.parent = &intf->dev; 17827791bdae71243050132ede7ea1558c828b69458fDmitry Torokhov 17837791bdae71243050132ede7ea1558c828b69458fDmitry Torokhov input_set_drvdata(inputdev, aiptek); 17847791bdae71243050132ede7ea1558c828b69458fDmitry Torokhov 1785c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov inputdev->open = aiptek_open; 1786c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov inputdev->close = aiptek_close; 17871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Now program the capacities of the tablet, in terms of being 17891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * an input device. 17901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 17911a54f49e8989462cfc9cab0c377b2d4e60e5b70aRene van Paassen for (i = 0; i < ARRAY_SIZE(eventTypes); ++i) 17921a54f49e8989462cfc9cab0c377b2d4e60e5b70aRene van Paassen __set_bit(eventTypes[i], inputdev->evbit); 17931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17941a54f49e8989462cfc9cab0c377b2d4e60e5b70aRene van Paassen for (i = 0; i < ARRAY_SIZE(absEvents); ++i) 17951a54f49e8989462cfc9cab0c377b2d4e60e5b70aRene van Paassen __set_bit(absEvents[i], inputdev->absbit); 17961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17971a54f49e8989462cfc9cab0c377b2d4e60e5b70aRene van Paassen for (i = 0; i < ARRAY_SIZE(relEvents); ++i) 17981a54f49e8989462cfc9cab0c377b2d4e60e5b70aRene van Paassen __set_bit(relEvents[i], inputdev->relbit); 17991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18001a54f49e8989462cfc9cab0c377b2d4e60e5b70aRene van Paassen __set_bit(MSC_SERIAL, inputdev->mscbit); 18011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 180233936fa603f2524a7dde08d22637d0989a4e8fddDmitry Torokhov /* Set up key and button codes */ 180333936fa603f2524a7dde08d22637d0989a4e8fddDmitry Torokhov for (i = 0; i < ARRAY_SIZE(buttonEvents); ++i) 180433936fa603f2524a7dde08d22637d0989a4e8fddDmitry Torokhov __set_bit(buttonEvents[i], inputdev->keybit); 180533936fa603f2524a7dde08d22637d0989a4e8fddDmitry Torokhov 180652950ed40dc97456209979af1d8f51b63cf6dcabTobias Klauser for (i = 0; i < ARRAY_SIZE(macroKeyEvents); ++i) 180733936fa603f2524a7dde08d22637d0989a4e8fddDmitry Torokhov __set_bit(macroKeyEvents[i], inputdev->keybit); 18081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1809c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov /* 1810c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov * Program the input device coordinate capacities. We do not yet 18111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * know what maximum X, Y, and Z values are, so we're putting fake 18121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * values in. Later, we'll ask the tablet to put in the correct 18131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * values. 18141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1815c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov input_set_abs_params(inputdev, ABS_X, 0, 2999, 0, 0); 1816f873e3e88d52774633968826c5b7fa7bf9697999Riccardo Magliocchetti input_set_abs_params(inputdev, ABS_Y, 0, 2249, 0, 0); 1817c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov input_set_abs_params(inputdev, ABS_PRESSURE, 0, 511, 0, 0); 1818c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov input_set_abs_params(inputdev, ABS_TILT_X, AIPTEK_TILT_MIN, AIPTEK_TILT_MAX, 0, 0); 1819c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov input_set_abs_params(inputdev, ABS_TILT_Y, AIPTEK_TILT_MIN, AIPTEK_TILT_MAX, 0, 0); 1820c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov input_set_abs_params(inputdev, ABS_WHEEL, AIPTEK_WHEEL_MIN, AIPTEK_WHEEL_MAX - 1, 0, 0); 18211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds endpoint = &intf->altsetting[0].endpoint[0].desc; 18231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Go set up our URB, which is called when the tablet receives 18251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * input. 18261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 18271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds usb_fill_int_urb(aiptek->urb, 18281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->usbdev, 18291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds usb_rcvintpipe(aiptek->usbdev, 18301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds endpoint->bEndpointAddress), 18311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->data, 8, aiptek_irq, aiptek, 18321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds endpoint->bInterval); 18331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->urb->transfer_dma = aiptek->data_dma; 18351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; 18361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Program the tablet. This sets the tablet up in the mode 18381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * specified in newSetting, and also queries the tablet's 18391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * physical capacities. 18401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Sanity check: if a tablet doesn't like the slow programmatic 18421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * delay, we often get sizes of 0x0. Let's use that as an indicator 18431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * to try faster delays, up to 25 ms. If that logic fails, well, you'll 18441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * have to explain to us how your tablet thinks it's 0x0, and yet that's 18451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * not an error :-) 18461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 18471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 184852950ed40dc97456209979af1d8f51b63cf6dcabTobias Klauser for (i = 0; i < ARRAY_SIZE(speeds); ++i) { 18491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds aiptek->curSetting.programmableDelay = speeds[i]; 18501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (void)aiptek_program_tablet(aiptek); 1851987a6c0298260b7aa40702b349282554d6180e4bDaniel Mack if (input_abs_get_max(aiptek->inputdev, ABS_X) > 0) { 1852899ef6e7cf2f057fcfd8071b36de04117313242bGreg Kroah-Hartman dev_info(&intf->dev, 1853899ef6e7cf2f057fcfd8071b36de04117313242bGreg Kroah-Hartman "Aiptek using %d ms programming speed\n", 1854899ef6e7cf2f057fcfd8071b36de04117313242bGreg Kroah-Hartman aiptek->curSetting.programmableDelay); 18551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 18561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 18571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 18581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18596125a400354c4a02b9dad0e5d8128f9dc08cfd51Rene van Paassen /* Murphy says that some day someone will have a tablet that fails the 18606125a400354c4a02b9dad0e5d8128f9dc08cfd51Rene van Paassen above test. That's you, Frederic Rodrigo */ 18616125a400354c4a02b9dad0e5d8128f9dc08cfd51Rene van Paassen if (i == ARRAY_SIZE(speeds)) { 1862899ef6e7cf2f057fcfd8071b36de04117313242bGreg Kroah-Hartman dev_info(&intf->dev, 1863899ef6e7cf2f057fcfd8071b36de04117313242bGreg Kroah-Hartman "Aiptek tried all speeds, no sane response\n"); 1864482d74ceb09db45b5d19fd1ae3810b38afbc0518Julia Lawall goto fail3; 18656125a400354c4a02b9dad0e5d8128f9dc08cfd51Rene van Paassen } 18666125a400354c4a02b9dad0e5d8128f9dc08cfd51Rene van Paassen 18671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Associate this driver's struct with the usb interface. 18681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 18691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds usb_set_intfdata(intf, aiptek); 18701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Set up the sysfs files 18721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1873b087e1f3ee9ae4da49fdeca2b0f0f8fc5a886a79Dmitry Torokhov err = sysfs_create_group(&intf->dev.kobj, &aiptek_attribute_group); 18746125a400354c4a02b9dad0e5d8128f9dc08cfd51Rene van Paassen if (err) { 18751817b1692a2eab022e805d32e910f4556c89dce8Greg Kroah-Hartman dev_warn(&intf->dev, "cannot create sysfs group err: %d\n", 18761817b1692a2eab022e805d32e910f4556c89dce8Greg Kroah-Hartman err); 1877b087e1f3ee9ae4da49fdeca2b0f0f8fc5a886a79Dmitry Torokhov goto fail3; 18786125a400354c4a02b9dad0e5d8128f9dc08cfd51Rene van Paassen } 1879b087e1f3ee9ae4da49fdeca2b0f0f8fc5a886a79Dmitry Torokhov 1880b087e1f3ee9ae4da49fdeca2b0f0f8fc5a886a79Dmitry Torokhov /* Register the tablet as an Input Device 1881b087e1f3ee9ae4da49fdeca2b0f0f8fc5a886a79Dmitry Torokhov */ 1882b087e1f3ee9ae4da49fdeca2b0f0f8fc5a886a79Dmitry Torokhov err = input_register_device(aiptek->inputdev); 18836125a400354c4a02b9dad0e5d8128f9dc08cfd51Rene van Paassen if (err) { 18841817b1692a2eab022e805d32e910f4556c89dce8Greg Kroah-Hartman dev_warn(&intf->dev, 18851817b1692a2eab022e805d32e910f4556c89dce8Greg Kroah-Hartman "input_register_device returned err: %d\n", err); 1886b087e1f3ee9ae4da49fdeca2b0f0f8fc5a886a79Dmitry Torokhov goto fail4; 18876125a400354c4a02b9dad0e5d8128f9dc08cfd51Rene van Paassen } 18881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1889c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov 1890b087e1f3ee9ae4da49fdeca2b0f0f8fc5a886a79Dmitry Torokhov fail4: sysfs_remove_group(&intf->dev.kobj, &aiptek_attribute_group); 1891b087e1f3ee9ae4da49fdeca2b0f0f8fc5a886a79Dmitry Torokhov fail3: usb_free_urb(aiptek->urb); 1892997ea58eb92f9970b8af7aae48800d0ef43b9423Daniel Mack fail2: usb_free_coherent(usbdev, AIPTEK_PACKET_LENGTH, aiptek->data, 1893997ea58eb92f9970b8af7aae48800d0ef43b9423Daniel Mack aiptek->data_dma); 1894b087e1f3ee9ae4da49fdeca2b0f0f8fc5a886a79Dmitry Torokhov fail1: usb_set_intfdata(intf, NULL); 1895b087e1f3ee9ae4da49fdeca2b0f0f8fc5a886a79Dmitry Torokhov input_free_device(inputdev); 1896c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov kfree(aiptek); 18975014186de89708d0e9eed60526b698d5b786b707Dmitry Torokhov return err; 18981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 18991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*********************************************************************** 19011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Deal with tablet disconnecting from the system. 19021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 19031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void aiptek_disconnect(struct usb_interface *intf) 19041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 19051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct aiptek *aiptek = usb_get_intfdata(intf); 19061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Disassociate driver's struct with usb interface 19081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 19091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds usb_set_intfdata(intf, NULL); 19101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (aiptek != NULL) { 19111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Free & unhook everything from the system. 19121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 19131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds usb_kill_urb(aiptek->urb); 1914c5b7c7c395a34f12cdf246d66c1feeff2933d584Dmitry Torokhov input_unregister_device(aiptek->inputdev); 1915b087e1f3ee9ae4da49fdeca2b0f0f8fc5a886a79Dmitry Torokhov sysfs_remove_group(&intf->dev.kobj, &aiptek_attribute_group); 19161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds usb_free_urb(aiptek->urb); 1917997ea58eb92f9970b8af7aae48800d0ef43b9423Daniel Mack usb_free_coherent(interface_to_usbdev(intf), 1918997ea58eb92f9970b8af7aae48800d0ef43b9423Daniel Mack AIPTEK_PACKET_LENGTH, 1919997ea58eb92f9970b8af7aae48800d0ef43b9423Daniel Mack aiptek->data, aiptek->data_dma); 19201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(aiptek); 19211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 19221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 19231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19245014186de89708d0e9eed60526b698d5b786b707Dmitry Torokhovstatic struct usb_driver aiptek_driver = { 19255014186de89708d0e9eed60526b698d5b786b707Dmitry Torokhov .name = "aiptek", 19265014186de89708d0e9eed60526b698d5b786b707Dmitry Torokhov .probe = aiptek_probe, 19275014186de89708d0e9eed60526b698d5b786b707Dmitry Torokhov .disconnect = aiptek_disconnect, 19285014186de89708d0e9eed60526b698d5b786b707Dmitry Torokhov .id_table = aiptek_ids, 19295014186de89708d0e9eed60526b698d5b786b707Dmitry Torokhov}; 19305014186de89708d0e9eed60526b698d5b786b707Dmitry Torokhov 193108642e7c52cf43616821520828e504bc717e54a6Greg Kroah-Hartmanmodule_usb_driver(aiptek_driver); 19321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_AUTHOR(DRIVER_AUTHOR); 19341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_DESCRIPTION(DRIVER_DESC); 19351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL"); 19361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_param(programmableDelay, int, 0); 19381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_PARM_DESC(programmableDelay, "delay used during tablet programming"); 19391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_param(jitterDelay, int, 0); 19401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_PARM_DESC(jitterDelay, "stylus/mouse settlement delay"); 1941