^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Native support for the Aiptek HyperPen USB Tablets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * (4000U/5000U/6000U/8000U/12000U)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (c) 2001 Chris Atenasio <chris@crud.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (c) 2002-2004 Bryan W. Headley <bwheadley@earthlink.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * based on wacom.c by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Vojtech Pavlik <vojtech@suse.cz>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Andreas Bach Aaen <abach@stofanet.dk>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Clifford Wolf <clifford@clifford.at>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * Sam Mosel <sam.mosel@computer.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * James E. Blair <corvus@gnu.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * Daniel Egger <egger@suse.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * Many thanks to Oliver Kuechemann for his support.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * ChangeLog:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * v0.1 - Initial release
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * v0.2 - Hack to get around fake event 28's. (Bryan W. Headley)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * v0.3 - Make URB dynamic (Bryan W. Headley, Jun-8-2002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * Released to Linux 2.4.19 and 2.5.x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * v0.4 - Rewrote substantial portions of the code to deal with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * corrected control sequences, timing, dynamic configuration,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * support of 6000U - 12000U, procfs, and macro key support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * (Jan-1-2003 - Feb-5-2003, Bryan W. Headley)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * v1.0 - Added support for diagnostic messages, count of messages
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * received from URB - Mar-8-2003, Bryan W. Headley
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * v1.1 - added support for tablet resolution, changed DV and proximity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * some corrections - Jun-22-2003, martin schneebacher
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * - Added support for the sysfs interface, deprecating the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * procfs interface for 2.5.x kernel. Also added support for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * Wheel command. Bryan W. Headley July-15-2003.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * v1.2 - Reworked jitter timer as a kernel thread.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * Bryan W. Headley November-28-2003/Jan-10-2004.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * v1.3 - Repaired issue of kernel thread going nuts on single-processor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * machines, introduced programmableDelay as a command line
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * parameter. Feb 7 2004, Bryan W. Headley.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * v1.4 - Re-wire jitter so it does not require a thread. Courtesy of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * Rene van Paassen. Added reporting of physical pointer device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * (e.g., stylus, mouse in reports 2, 3, 4, 5. We don't know
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * for reports 1, 6.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * what physical device reports for reports 1, 6.) Also enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * MOUSE and LENS tool button modes. Renamed "rubber" to "eraser".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * Feb 20, 2004, Bryan W. Headley.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * v1.5 - Added previousJitterable, so we don't do jitter delay when the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * user is holding a button down for periods of time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * NOTE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * This kernel driver is augmented by the "Aiptek" XFree86 input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * driver for your X server, as well as the Gaiptek GUI Front-end
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * "Tablet Manager".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * These three products are highly interactive with one another,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * so therefore it's easier to document them all as one subsystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * Please visit the project's "home page", located at,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * http://aiptektablet.sourceforge.net.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #include <linux/jiffies.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #include <linux/usb/input.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #include <asm/unaligned.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * Aiptek status packet:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * (returned as Report 1 - relative coordinates from mouse and stylus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * byte0 0 0 0 0 0 0 0 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * byte1 0 0 0 0 0 BS2 BS Tip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * byte2 X7 X6 X5 X4 X3 X2 X1 X0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * byte3 Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * (returned as Report 2 - absolute coordinates from the stylus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * byte0 0 0 0 0 0 0 1 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * byte1 X7 X6 X5 X4 X3 X2 X1 X0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * byte2 X15 X14 X13 X12 X11 X10 X9 X8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * byte3 Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * byte4 Y15 Y14 Y13 Y12 Y11 Y10 Y9 Y8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * byte5 * * * BS2 BS1 Tip IR DV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * byte6 P7 P6 P5 P4 P3 P2 P1 P0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * byte7 P15 P14 P13 P12 P11 P10 P9 P8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * (returned as Report 3 - absolute coordinates from the mouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * byte0 0 0 0 0 0 0 1 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * byte1 X7 X6 X5 X4 X3 X2 X1 X0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * byte2 X15 X14 X13 X12 X11 X10 X9 X8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * byte3 Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * byte4 Y15 Y14 Y13 Y12 Y11 Y10 Y9 Y8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * byte5 * * * BS2 BS1 Tip IR DV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * byte6 P7 P6 P5 P4 P3 P2 P1 P0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * byte7 P15 P14 P13 P12 P11 P10 P9 P8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * (returned as Report 4 - macrokeys from the stylus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * byte0 0 0 0 0 0 1 0 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * byte1 0 0 0 BS2 BS Tip IR DV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * byte2 0 0 0 0 0 0 1 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * byte3 0 0 0 K4 K3 K2 K1 K0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * byte4 P7 P6 P5 P4 P3 P2 P1 P0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * byte5 P15 P14 P13 P12 P11 P10 P9 P8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * (returned as Report 5 - macrokeys from the mouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * byte0 0 0 0 0 0 1 0 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * byte1 0 0 0 BS2 BS Tip IR DV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * byte2 0 0 0 0 0 0 1 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * byte3 0 0 0 K4 K3 K2 K1 K0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * byte4 P7 P6 P5 P4 P3 P2 P1 P0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * byte5 P15 P14 P13 P12 P11 P10 P9 P8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * IR: In Range = Proximity on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * DV = Data Valid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * BS = Barrel Switch (as in, macro keys)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * BS2 also referred to as Tablet Pick
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * Command Summary:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * Use report_type CONTROL (3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * Use report_id 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * Command/Data Description Return Bytes Return Value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * 0x10/0x00 SwitchToMouse 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * 0x10/0x01 SwitchToTablet 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * 0x18/0x04 SetResolution 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * 0x12/0xFF AutoGainOn 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * 0x17/0x00 FilterOn 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) * 0x01/0x00 GetXExtension 2 MaxX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * 0x01/0x01 GetYExtension 2 MaxY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * 0x02/0x00 GetModelCode 2 ModelCode = LOBYTE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * 0x03/0x00 GetODMCode 2 ODMCode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * 0x08/0x00 GetPressureLevels 2 =512
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * 0x04/0x00 GetFirmwareVersion 2 Firmware Version
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * 0x11/0x02 EnableMacroKeys 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * To initialize the tablet:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * (1) Send Resolution500LPI (Command)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * (2) Query for Model code (Option Report)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * (3) Query for ODM code (Option Report)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * (4) Query for firmware (Option Report)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * (5) Query for GetXExtension (Option Report)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * (6) Query for GetYExtension (Option Report)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * (7) Query for GetPressureLevels (Option Report)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * (8) SwitchToTablet for Absolute coordinates, or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * SwitchToMouse for Relative coordinates (Command)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * (9) EnableMacroKeys (Command)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * (10) FilterOn (Command)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * (11) AutoGainOn (Command)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) * (Step 9 can be omitted, but you'll then have no function keys.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) #define USB_VENDOR_ID_AIPTEK 0x08ca
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) #define USB_VENDOR_ID_KYE 0x0458
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) #define USB_REQ_GET_REPORT 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) #define USB_REQ_SET_REPORT 0x09
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) /* PointerMode codes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) #define AIPTEK_POINTER_ONLY_MOUSE_MODE 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) #define AIPTEK_POINTER_ONLY_STYLUS_MODE 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) #define AIPTEK_POINTER_EITHER_MODE 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) #define AIPTEK_POINTER_ALLOW_MOUSE_MODE(a) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) (a == AIPTEK_POINTER_ONLY_MOUSE_MODE || \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) a == AIPTEK_POINTER_EITHER_MODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) #define AIPTEK_POINTER_ALLOW_STYLUS_MODE(a) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) (a == AIPTEK_POINTER_ONLY_STYLUS_MODE || \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) a == AIPTEK_POINTER_EITHER_MODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) /* CoordinateMode code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) #define AIPTEK_COORDINATE_RELATIVE_MODE 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) #define AIPTEK_COORDINATE_ABSOLUTE_MODE 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) /* XTilt and YTilt values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) #define AIPTEK_TILT_MIN (-128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) #define AIPTEK_TILT_MAX 127
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) #define AIPTEK_TILT_DISABLE (-10101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /* Wheel values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) #define AIPTEK_WHEEL_MIN 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) #define AIPTEK_WHEEL_MAX 1024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) #define AIPTEK_WHEEL_DISABLE (-10101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) /* ToolCode values, which BTW are 0x140 .. 0x14f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) * We have things set up such that if the tool button has changed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) * the tools get reset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) /* toolMode codes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) #define AIPTEK_TOOL_BUTTON_PEN_MODE BTN_TOOL_PEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) #define AIPTEK_TOOL_BUTTON_PENCIL_MODE BTN_TOOL_PENCIL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) #define AIPTEK_TOOL_BUTTON_BRUSH_MODE BTN_TOOL_BRUSH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) #define AIPTEK_TOOL_BUTTON_AIRBRUSH_MODE BTN_TOOL_AIRBRUSH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) #define AIPTEK_TOOL_BUTTON_ERASER_MODE BTN_TOOL_RUBBER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) #define AIPTEK_TOOL_BUTTON_MOUSE_MODE BTN_TOOL_MOUSE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) #define AIPTEK_TOOL_BUTTON_LENS_MODE BTN_TOOL_LENS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) /* Diagnostic message codes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) #define AIPTEK_DIAGNOSTIC_NA 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) #define AIPTEK_DIAGNOSTIC_SENDING_RELATIVE_IN_ABSOLUTE 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) #define AIPTEK_DIAGNOSTIC_SENDING_ABSOLUTE_IN_RELATIVE 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) #define AIPTEK_DIAGNOSTIC_TOOL_DISALLOWED 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) /* Time to wait (in ms) to help mask hand jittering
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) * when pressing the stylus buttons.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) #define AIPTEK_JITTER_DELAY_DEFAULT 50
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) /* Time to wait (in ms) in-between sending the tablet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) * a command and beginning the process of reading the return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * sequence from the tablet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) #define AIPTEK_PROGRAMMABLE_DELAY_25 25
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) #define AIPTEK_PROGRAMMABLE_DELAY_50 50
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) #define AIPTEK_PROGRAMMABLE_DELAY_100 100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) #define AIPTEK_PROGRAMMABLE_DELAY_200 200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) #define AIPTEK_PROGRAMMABLE_DELAY_300 300
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) #define AIPTEK_PROGRAMMABLE_DELAY_400 400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) #define AIPTEK_PROGRAMMABLE_DELAY_DEFAULT AIPTEK_PROGRAMMABLE_DELAY_400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) /* Mouse button programming
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) #define AIPTEK_MOUSE_LEFT_BUTTON 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) #define AIPTEK_MOUSE_RIGHT_BUTTON 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) #define AIPTEK_MOUSE_MIDDLE_BUTTON 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) /* Stylus button programming
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) #define AIPTEK_STYLUS_LOWER_BUTTON 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) #define AIPTEK_STYLUS_UPPER_BUTTON 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) /* Length of incoming packet from the tablet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) #define AIPTEK_PACKET_LENGTH 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) /* We report in EV_MISC both the proximity and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) * whether the report came from the stylus, tablet mouse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * or "unknown" -- Unknown when the tablet is in relative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) * mode, because we only get report 1's.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) #define AIPTEK_REPORT_TOOL_UNKNOWN 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) #define AIPTEK_REPORT_TOOL_STYLUS 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) #define AIPTEK_REPORT_TOOL_MOUSE 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) static int programmableDelay = AIPTEK_PROGRAMMABLE_DELAY_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) static int jitterDelay = AIPTEK_JITTER_DELAY_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) struct aiptek_features {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) int odmCode; /* Tablet manufacturer code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) int modelCode; /* Tablet model code (not unique) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) int firmwareCode; /* prom/eeprom version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) char usbPath[64 + 1]; /* device's physical usb path */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) struct aiptek_settings {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) int pointerMode; /* stylus-, mouse-only or either */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) int coordinateMode; /* absolute/relative coords */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) int toolMode; /* pen, pencil, brush, etc. tool */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) int xTilt; /* synthetic xTilt amount */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) int yTilt; /* synthetic yTilt amount */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) int wheel; /* synthetic wheel amount */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) int stylusButtonUpper; /* stylus upper btn delivers... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) int stylusButtonLower; /* stylus lower btn delivers... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) int mouseButtonLeft; /* mouse left btn delivers... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) int mouseButtonMiddle; /* mouse middle btn delivers... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) int mouseButtonRight; /* mouse right btn delivers... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) int programmableDelay; /* delay for tablet programming */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) int jitterDelay; /* delay for hand jittering */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) struct aiptek {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) struct input_dev *inputdev; /* input device struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) struct usb_interface *intf; /* usb interface struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) struct urb *urb; /* urb for incoming reports */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) dma_addr_t data_dma; /* our dma stuffage */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) struct aiptek_features features; /* tablet's array of features */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) struct aiptek_settings curSetting; /* tablet's current programmable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) struct aiptek_settings newSetting; /* ... and new param settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) unsigned int ifnum; /* interface number for IO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) int diagnostic; /* tablet diagnostic codes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) unsigned long eventCount; /* event count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) int inDelay; /* jitter: in jitter delay? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) unsigned long endDelay; /* jitter: time when delay ends */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) int previousJitterable; /* jitterable prev value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) int lastMacro; /* macro key to reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) int previousToolMode; /* pen, pencil, brush, etc. tool */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) unsigned char *data; /* incoming packet data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) static const int eventTypes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) EV_KEY, EV_ABS, EV_REL, EV_MSC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) static const int absEvents[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) ABS_X, ABS_Y, ABS_PRESSURE, ABS_TILT_X, ABS_TILT_Y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) ABS_WHEEL, ABS_MISC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) static const int relEvents[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) REL_X, REL_Y, REL_WHEEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) static const int buttonEvents[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) BTN_LEFT, BTN_RIGHT, BTN_MIDDLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) BTN_TOOL_PEN, BTN_TOOL_RUBBER, BTN_TOOL_PENCIL, BTN_TOOL_AIRBRUSH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) BTN_TOOL_BRUSH, BTN_TOOL_MOUSE, BTN_TOOL_LENS, BTN_TOUCH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) BTN_STYLUS, BTN_STYLUS2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) * Permit easy lookup of keyboard events to send, versus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) * the bitmap which comes from the tablet. This hides the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) * issue that the F_keys are not sequentially numbered.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) static const int macroKeyEvents[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) KEY_ESC, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_F11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) KEY_F12, KEY_F13, KEY_F14, KEY_F15, KEY_F16, KEY_F17,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) KEY_F18, KEY_F19, KEY_F20, KEY_F21, KEY_F22, KEY_F23,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) KEY_F24, KEY_STOP, KEY_AGAIN, KEY_PROPS, KEY_UNDO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) KEY_FRONT, KEY_COPY, KEY_OPEN, KEY_PASTE, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) /***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) * Map values to strings and back. Every map should have the following
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) * as its last element: { NULL, AIPTEK_INVALID_VALUE }.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) #define AIPTEK_INVALID_VALUE -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) struct aiptek_map {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) const char *string;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) int value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) static int map_str_to_val(const struct aiptek_map *map, const char *str, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) const struct aiptek_map *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (str[count - 1] == '\n')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) for (p = map; p->string; p++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) if (!strncmp(str, p->string, count))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) return p->value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) return AIPTEK_INVALID_VALUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) static const char *map_val_to_str(const struct aiptek_map *map, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) const struct aiptek_map *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) for (p = map; p->value != AIPTEK_INVALID_VALUE; p++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if (val == p->value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) return p->string;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) return "unknown";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) /***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) * aiptek_irq can receive one of six potential reports.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) * The documentation for each is in the body of the function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) * The tablet reports on several attributes per invocation of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) * aiptek_irq. Because the Linux Input Event system allows the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) * transmission of ONE attribute per input_report_xxx() call,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) * collation has to be done on the other end to reconstitute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) * a complete tablet report. Further, the number of Input Event reports
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) * submitted varies, depending on what USB report type, and circumstance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) * To deal with this, EV_MSC is used to indicate an 'end-of-report'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) * message. This has been an undocumented convention understood by the kernel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) * tablet driver and clients such as gpm and XFree86's tablet drivers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) * Of the information received from the tablet, the one piece I
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) * cannot transmit is the proximity bit (without resorting to an EV_MSC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) * convention above.) I therefore have taken over REL_MISC and ABS_MISC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) * (for relative and absolute reports, respectively) for communicating
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) * Proximity. Why two events? I thought it interesting to know if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) * Proximity event occurred while the tablet was in absolute or relative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) * mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) * Update: REL_MISC proved not to be such a good idea. With REL_MISC you
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) * get an event transmitted each time. ABS_MISC works better, since it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) * can be set and re-set. Thus, only using ABS_MISC from now on.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) * Other tablets use the notion of a certain minimum stylus pressure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) * to infer proximity. While that could have been done, that is yet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) * another 'by convention' behavior, the documentation for which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) * would be spread between two (or more) pieces of software.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) * EV_MSC usage was terminated for this purpose in Linux 2.5.x, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) * replaced with the input_sync() method (which emits EV_SYN.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) static void aiptek_irq(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) struct aiptek *aiptek = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) unsigned char *data = aiptek->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) struct input_dev *inputdev = aiptek->inputdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) struct usb_interface *intf = aiptek->intf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) int jitterable = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) int retval, macro, x, y, z, left, right, middle, p, dv, tip, bs, pck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) switch (urb->status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) /* Success */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) case -ECONNRESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) case -ENOENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) case -ESHUTDOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) /* This urb is terminated, clean up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) dev_dbg(&intf->dev, "%s - urb shutting down with status: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) __func__, urb->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) dev_dbg(&intf->dev, "%s - nonzero urb status received: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) __func__, urb->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) /* See if we are in a delay loop -- throw out report if true.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) if (aiptek->inDelay == 1 && time_after(aiptek->endDelay, jiffies)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) aiptek->inDelay = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) aiptek->eventCount++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) /* Report 1 delivers relative coordinates with either a stylus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) * or the mouse. You do not know, however, which input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) * tool generated the event.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) if (data[0] == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if (aiptek->curSetting.coordinateMode ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) AIPTEK_COORDINATE_ABSOLUTE_MODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) aiptek->diagnostic =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) AIPTEK_DIAGNOSTIC_SENDING_RELATIVE_IN_ABSOLUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) x = (signed char) data[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) y = (signed char) data[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) /* jitterable keeps track of whether any button has been pressed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) * We're also using it to remap the physical mouse button mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) * to pseudo-settings. (We don't specifically care about it's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) * value after moving/transposing mouse button bitmasks, except
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) * that a non-zero value indicates that one or more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) * mouse button was pressed.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) jitterable = data[1] & 0x07;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) left = (data[1] & aiptek->curSetting.mouseButtonLeft >> 2) != 0 ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) right = (data[1] & aiptek->curSetting.mouseButtonRight >> 2) != 0 ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) middle = (data[1] & aiptek->curSetting.mouseButtonMiddle >> 2) != 0 ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) input_report_key(inputdev, BTN_LEFT, left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) input_report_key(inputdev, BTN_MIDDLE, middle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) input_report_key(inputdev, BTN_RIGHT, right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) input_report_abs(inputdev, ABS_MISC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 1 | AIPTEK_REPORT_TOOL_UNKNOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) input_report_rel(inputdev, REL_X, x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) input_report_rel(inputdev, REL_Y, y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) /* Wheel support is in the form of a single-event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) * firing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (aiptek->curSetting.wheel != AIPTEK_WHEEL_DISABLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) input_report_rel(inputdev, REL_WHEEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) aiptek->curSetting.wheel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) aiptek->curSetting.wheel = AIPTEK_WHEEL_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (aiptek->lastMacro != -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) input_report_key(inputdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) macroKeyEvents[aiptek->lastMacro], 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) aiptek->lastMacro = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) input_sync(inputdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) /* Report 2 is delivered only by the stylus, and delivers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) * absolute coordinates.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) else if (data[0] == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) if (aiptek->curSetting.coordinateMode == AIPTEK_COORDINATE_RELATIVE_MODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) aiptek->diagnostic = AIPTEK_DIAGNOSTIC_SENDING_ABSOLUTE_IN_RELATIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) } else if (!AIPTEK_POINTER_ALLOW_STYLUS_MODE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) (aiptek->curSetting.pointerMode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) aiptek->diagnostic = AIPTEK_DIAGNOSTIC_TOOL_DISALLOWED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) x = get_unaligned_le16(data + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) y = get_unaligned_le16(data + 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) z = get_unaligned_le16(data + 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) dv = (data[5] & 0x01) != 0 ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) p = (data[5] & 0x02) != 0 ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) tip = (data[5] & 0x04) != 0 ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) /* Use jitterable to re-arrange button masks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) jitterable = data[5] & 0x18;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) bs = (data[5] & aiptek->curSetting.stylusButtonLower) != 0 ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) pck = (data[5] & aiptek->curSetting.stylusButtonUpper) != 0 ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) /* dv indicates 'data valid' (e.g., the tablet is in sync
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) * and has delivered a "correct" report) We will ignore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) * all 'bad' reports...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) if (dv != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) /* If the selected tool changed, reset the old
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) * tool key, and set the new one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) if (aiptek->previousToolMode !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) aiptek->curSetting.toolMode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) input_report_key(inputdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) aiptek->previousToolMode, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) input_report_key(inputdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) aiptek->curSetting.toolMode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) aiptek->previousToolMode =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) aiptek->curSetting.toolMode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) if (p != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) input_report_abs(inputdev, ABS_X, x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) input_report_abs(inputdev, ABS_Y, y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) input_report_abs(inputdev, ABS_PRESSURE, z);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) input_report_key(inputdev, BTN_TOUCH, tip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) input_report_key(inputdev, BTN_STYLUS, bs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) input_report_key(inputdev, BTN_STYLUS2, pck);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if (aiptek->curSetting.xTilt !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) AIPTEK_TILT_DISABLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) input_report_abs(inputdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) ABS_TILT_X,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) aiptek->curSetting.xTilt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) if (aiptek->curSetting.yTilt != AIPTEK_TILT_DISABLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) input_report_abs(inputdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) ABS_TILT_Y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) aiptek->curSetting.yTilt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) /* Wheel support is in the form of a single-event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) * firing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) if (aiptek->curSetting.wheel !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) AIPTEK_WHEEL_DISABLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) input_report_abs(inputdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) ABS_WHEEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) aiptek->curSetting.wheel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) aiptek->curSetting.wheel = AIPTEK_WHEEL_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) input_report_abs(inputdev, ABS_MISC, p | AIPTEK_REPORT_TOOL_STYLUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) if (aiptek->lastMacro != -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) input_report_key(inputdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) macroKeyEvents[aiptek->lastMacro], 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) aiptek->lastMacro = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) input_sync(inputdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) /* Report 3's come from the mouse in absolute mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) else if (data[0] == 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) if (aiptek->curSetting.coordinateMode == AIPTEK_COORDINATE_RELATIVE_MODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) aiptek->diagnostic = AIPTEK_DIAGNOSTIC_SENDING_ABSOLUTE_IN_RELATIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) } else if (!AIPTEK_POINTER_ALLOW_MOUSE_MODE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) (aiptek->curSetting.pointerMode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) aiptek->diagnostic = AIPTEK_DIAGNOSTIC_TOOL_DISALLOWED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) x = get_unaligned_le16(data + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) y = get_unaligned_le16(data + 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) jitterable = data[5] & 0x1c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) dv = (data[5] & 0x01) != 0 ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) p = (data[5] & 0x02) != 0 ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) left = (data[5] & aiptek->curSetting.mouseButtonLeft) != 0 ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) right = (data[5] & aiptek->curSetting.mouseButtonRight) != 0 ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) middle = (data[5] & aiptek->curSetting.mouseButtonMiddle) != 0 ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) if (dv != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) /* If the selected tool changed, reset the old
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) * tool key, and set the new one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) if (aiptek->previousToolMode !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) aiptek->curSetting.toolMode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) input_report_key(inputdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) aiptek->previousToolMode, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) input_report_key(inputdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) aiptek->curSetting.toolMode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) aiptek->previousToolMode =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) aiptek->curSetting.toolMode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) if (p != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) input_report_abs(inputdev, ABS_X, x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) input_report_abs(inputdev, ABS_Y, y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) input_report_key(inputdev, BTN_LEFT, left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) input_report_key(inputdev, BTN_MIDDLE, middle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) input_report_key(inputdev, BTN_RIGHT, right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) /* Wheel support is in the form of a single-event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) * firing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) if (aiptek->curSetting.wheel != AIPTEK_WHEEL_DISABLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) input_report_abs(inputdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) ABS_WHEEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) aiptek->curSetting.wheel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) aiptek->curSetting.wheel = AIPTEK_WHEEL_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) input_report_abs(inputdev, ABS_MISC, p | AIPTEK_REPORT_TOOL_MOUSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) if (aiptek->lastMacro != -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) input_report_key(inputdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) macroKeyEvents[aiptek->lastMacro], 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) aiptek->lastMacro = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) input_sync(inputdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) /* Report 4s come from the macro keys when pressed by stylus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) else if (data[0] == 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) jitterable = data[1] & 0x18;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) dv = (data[1] & 0x01) != 0 ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) p = (data[1] & 0x02) != 0 ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) tip = (data[1] & 0x04) != 0 ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) bs = (data[1] & aiptek->curSetting.stylusButtonLower) != 0 ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) pck = (data[1] & aiptek->curSetting.stylusButtonUpper) != 0 ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) macro = dv && p && tip && !(data[3] & 1) ? (data[3] >> 1) : -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) z = get_unaligned_le16(data + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) if (dv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) /* If the selected tool changed, reset the old
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) * tool key, and set the new one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) if (aiptek->previousToolMode !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) aiptek->curSetting.toolMode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) input_report_key(inputdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) aiptek->previousToolMode, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) input_report_key(inputdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) aiptek->curSetting.toolMode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) aiptek->previousToolMode =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) aiptek->curSetting.toolMode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) if (aiptek->lastMacro != -1 && aiptek->lastMacro != macro) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) input_report_key(inputdev, macroKeyEvents[aiptek->lastMacro], 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) aiptek->lastMacro = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) if (macro != -1 && macro != aiptek->lastMacro) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) input_report_key(inputdev, macroKeyEvents[macro], 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) aiptek->lastMacro = macro;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) input_report_abs(inputdev, ABS_MISC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) p | AIPTEK_REPORT_TOOL_STYLUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) input_sync(inputdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) /* Report 5s come from the macro keys when pressed by mouse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) else if (data[0] == 5) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) jitterable = data[1] & 0x1c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) dv = (data[1] & 0x01) != 0 ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) p = (data[1] & 0x02) != 0 ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) left = (data[1]& aiptek->curSetting.mouseButtonLeft) != 0 ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) right = (data[1] & aiptek->curSetting.mouseButtonRight) != 0 ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) middle = (data[1] & aiptek->curSetting.mouseButtonMiddle) != 0 ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) macro = dv && p && left && !(data[3] & 1) ? (data[3] >> 1) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) if (dv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) /* If the selected tool changed, reset the old
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) * tool key, and set the new one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) if (aiptek->previousToolMode !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) aiptek->curSetting.toolMode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) input_report_key(inputdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) aiptek->previousToolMode, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) input_report_key(inputdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) aiptek->curSetting.toolMode, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) aiptek->previousToolMode = aiptek->curSetting.toolMode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) if (aiptek->lastMacro != -1 && aiptek->lastMacro != macro) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) input_report_key(inputdev, macroKeyEvents[aiptek->lastMacro], 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) aiptek->lastMacro = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) if (macro != -1 && macro != aiptek->lastMacro) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) input_report_key(inputdev, macroKeyEvents[macro], 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) aiptek->lastMacro = macro;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) input_report_abs(inputdev, ABS_MISC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) p | AIPTEK_REPORT_TOOL_MOUSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) input_sync(inputdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) /* We have no idea which tool can generate a report 6. Theoretically,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) * neither need to, having been given reports 4 & 5 for such use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) * However, report 6 is the 'official-looking' report for macroKeys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) * reports 4 & 5 supposively are used to support unnamed, unknown
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) * hat switches (which just so happen to be the macroKeys.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) else if (data[0] == 6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) macro = get_unaligned_le16(data + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) if (macro > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) input_report_key(inputdev, macroKeyEvents[macro - 1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) if (macro < 25) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) input_report_key(inputdev, macroKeyEvents[macro + 1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) /* If the selected tool changed, reset the old
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) tool key, and set the new one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) if (aiptek->previousToolMode !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) aiptek->curSetting.toolMode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) input_report_key(inputdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) aiptek->previousToolMode, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) input_report_key(inputdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) aiptek->curSetting.toolMode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) aiptek->previousToolMode =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) aiptek->curSetting.toolMode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) input_report_key(inputdev, macroKeyEvents[macro], 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) input_report_abs(inputdev, ABS_MISC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) 1 | AIPTEK_REPORT_TOOL_UNKNOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) input_sync(inputdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) dev_dbg(&intf->dev, "Unknown report %d\n", data[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) /* Jitter may occur when the user presses a button on the stlyus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) * or the mouse. What we do to prevent that is wait 'x' milliseconds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) * following a 'jitterable' event, which should give the hand some time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) * stabilize itself.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) * We just introduced aiptek->previousJitterable to carry forth the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) * notion that jitter occurs when the button state changes from on to off:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) * a person drawing, holding a button down is not subject to jittering.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) * With that in mind, changing from upper button depressed to lower button
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) * WILL transition through a jitter delay.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) if (aiptek->previousJitterable != jitterable &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) aiptek->curSetting.jitterDelay != 0 && aiptek->inDelay != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) aiptek->endDelay = jiffies +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) ((aiptek->curSetting.jitterDelay * HZ) / 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) aiptek->inDelay = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) aiptek->previousJitterable = jitterable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) retval = usb_submit_urb(urb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) if (retval != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) dev_err(&intf->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) "%s - usb_submit_urb failed with result %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) __func__, retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) /***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) * These are the USB id's known so far. We do not identify them to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) * specific Aiptek model numbers, because there has been overlaps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) * use, and reuse of id's in existing models. Certain models have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) * been known to use more than one ID, indicative perhaps of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) * manufacturing revisions. In any event, we consider these
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) * IDs to not be model-specific nor unique.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) static const struct usb_device_id aiptek_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) {USB_DEVICE(USB_VENDOR_ID_AIPTEK, 0x01)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) {USB_DEVICE(USB_VENDOR_ID_AIPTEK, 0x10)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) {USB_DEVICE(USB_VENDOR_ID_AIPTEK, 0x20)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) {USB_DEVICE(USB_VENDOR_ID_AIPTEK, 0x21)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) {USB_DEVICE(USB_VENDOR_ID_AIPTEK, 0x22)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) {USB_DEVICE(USB_VENDOR_ID_AIPTEK, 0x23)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) {USB_DEVICE(USB_VENDOR_ID_AIPTEK, 0x24)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) {USB_DEVICE(USB_VENDOR_ID_KYE, 0x5003)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) MODULE_DEVICE_TABLE(usb, aiptek_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) /***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) * Open an instance of the tablet driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) static int aiptek_open(struct input_dev *inputdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) struct aiptek *aiptek = input_get_drvdata(inputdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) aiptek->urb->dev = interface_to_usbdev(aiptek->intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) if (usb_submit_urb(aiptek->urb, GFP_KERNEL) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) /***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) * Close an instance of the tablet driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) static void aiptek_close(struct input_dev *inputdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) struct aiptek *aiptek = input_get_drvdata(inputdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) usb_kill_urb(aiptek->urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) /***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) * aiptek_set_report and aiptek_get_report() are borrowed from Linux 2.4.x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) * where they were known as usb_set_report and usb_get_report.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) aiptek_set_report(struct aiptek *aiptek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) unsigned char report_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) unsigned char report_id, void *buffer, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) struct usb_device *udev = interface_to_usbdev(aiptek->intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) return usb_control_msg(udev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) usb_sndctrlpipe(udev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) USB_REQ_SET_REPORT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) USB_TYPE_CLASS | USB_RECIP_INTERFACE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) USB_DIR_OUT, (report_type << 8) + report_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) aiptek->ifnum, buffer, size, 5000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) aiptek_get_report(struct aiptek *aiptek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) unsigned char report_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) unsigned char report_id, void *buffer, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) struct usb_device *udev = interface_to_usbdev(aiptek->intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) return usb_control_msg(udev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) usb_rcvctrlpipe(udev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) USB_REQ_GET_REPORT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) USB_TYPE_CLASS | USB_RECIP_INTERFACE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) USB_DIR_IN, (report_type << 8) + report_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) aiptek->ifnum, buffer, size, 5000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) /***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) * Send a command to the tablet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) aiptek_command(struct aiptek *aiptek, unsigned char command, unsigned char data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) const int sizeof_buf = 3 * sizeof(u8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) u8 *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) buf = kmalloc(sizeof_buf, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) buf[0] = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) buf[1] = command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) buf[2] = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) if ((ret =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) aiptek_set_report(aiptek, 3, 2, buf, sizeof_buf)) != sizeof_buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) dev_dbg(&aiptek->intf->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) "aiptek_program: failed, tried to send: 0x%02x 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) command, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) return ret < 0 ? ret : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) /***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) * Retrieve information from the tablet. Querying info is defined as first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) * sending the {command,data} sequence as a command, followed by a wait
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) * (aka, "programmaticDelay") and then a "read" request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) aiptek_query(struct aiptek *aiptek, unsigned char command, unsigned char data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) const int sizeof_buf = 3 * sizeof(u8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) u8 *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) buf = kmalloc(sizeof_buf, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) buf[0] = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) buf[1] = command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) buf[2] = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) if (aiptek_command(aiptek, command, data) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) msleep(aiptek->curSetting.programmableDelay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) if ((ret =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) aiptek_get_report(aiptek, 3, 2, buf, sizeof_buf)) != sizeof_buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) dev_dbg(&aiptek->intf->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) "aiptek_query failed: returned 0x%02x 0x%02x 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) buf[0], buf[1], buf[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) ret = get_unaligned_le16(buf + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) /***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) * Program the tablet into either absolute or relative mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) * We also get information about the tablet's size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) static int aiptek_program_tablet(struct aiptek *aiptek)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) /* Execute Resolution500LPI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) if ((ret = aiptek_command(aiptek, 0x18, 0x04)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) /* Query getModelCode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) if ((ret = aiptek_query(aiptek, 0x02, 0x00)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) aiptek->features.modelCode = ret & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) /* Query getODMCode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) if ((ret = aiptek_query(aiptek, 0x03, 0x00)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) aiptek->features.odmCode = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) /* Query getFirmwareCode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) if ((ret = aiptek_query(aiptek, 0x04, 0x00)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) aiptek->features.firmwareCode = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) /* Query getXextension */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) if ((ret = aiptek_query(aiptek, 0x01, 0x00)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) input_set_abs_params(aiptek->inputdev, ABS_X, 0, ret - 1, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) /* Query getYextension */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) if ((ret = aiptek_query(aiptek, 0x01, 0x01)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) input_set_abs_params(aiptek->inputdev, ABS_Y, 0, ret - 1, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) /* Query getPressureLevels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) if ((ret = aiptek_query(aiptek, 0x08, 0x00)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) input_set_abs_params(aiptek->inputdev, ABS_PRESSURE, 0, ret - 1, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) /* Depending on whether we are in absolute or relative mode, we will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) * do a switchToTablet(absolute) or switchToMouse(relative) command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) if (aiptek->curSetting.coordinateMode ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) AIPTEK_COORDINATE_ABSOLUTE_MODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) /* Execute switchToTablet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) if ((ret = aiptek_command(aiptek, 0x10, 0x01)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) /* Execute switchToMouse */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) if ((ret = aiptek_command(aiptek, 0x10, 0x00)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) /* Enable the macro keys */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) if ((ret = aiptek_command(aiptek, 0x11, 0x02)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) /* Execute FilterOn */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) if ((ret = aiptek_command(aiptek, 0x17, 0x00)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) /* Execute AutoGainOn */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) if ((ret = aiptek_command(aiptek, 0x12, 0xff)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) /* Reset the eventCount, so we track events from last (re)programming
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) aiptek->diagnostic = AIPTEK_DIAGNOSTIC_NA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) aiptek->eventCount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) /***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) * Sysfs functions. Sysfs prefers that individually-tunable parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) * exist in their separate pseudo-files. Summary data that is immutable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) * may exist in a singular file so long as you don't define a writeable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) * interface.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) /***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) * support the 'size' file -- display support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) static ssize_t show_tabletSize(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) struct aiptek *aiptek = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) return snprintf(buf, PAGE_SIZE, "%dx%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) input_abs_get_max(aiptek->inputdev, ABS_X) + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) input_abs_get_max(aiptek->inputdev, ABS_Y) + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) /* These structs define the sysfs files, param #1 is the name of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) * file, param 2 is the file permissions, param 3 & 4 are to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) * output generator and input parser routines. Absence of a routine is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) * permitted -- it only means can't either 'cat' the file, or send data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) * to it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) static DEVICE_ATTR(size, S_IRUGO, show_tabletSize, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) /***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) * support routines for the 'pointer_mode' file. Note that this file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) * both displays current setting and allows reprogramming.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) static struct aiptek_map pointer_mode_map[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) { "stylus", AIPTEK_POINTER_ONLY_STYLUS_MODE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) { "mouse", AIPTEK_POINTER_ONLY_MOUSE_MODE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) { "either", AIPTEK_POINTER_EITHER_MODE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) { NULL, AIPTEK_INVALID_VALUE }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) static ssize_t show_tabletPointerMode(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) struct aiptek *aiptek = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) return snprintf(buf, PAGE_SIZE, "%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) map_val_to_str(pointer_mode_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) aiptek->curSetting.pointerMode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) store_tabletPointerMode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) struct aiptek *aiptek = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) int new_mode = map_str_to_val(pointer_mode_map, buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) if (new_mode == AIPTEK_INVALID_VALUE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) aiptek->newSetting.pointerMode = new_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) static DEVICE_ATTR(pointer_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) show_tabletPointerMode, store_tabletPointerMode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) /***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) * support routines for the 'coordinate_mode' file. Note that this file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) * both displays current setting and allows reprogramming.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) static struct aiptek_map coordinate_mode_map[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) { "absolute", AIPTEK_COORDINATE_ABSOLUTE_MODE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) { "relative", AIPTEK_COORDINATE_RELATIVE_MODE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) { NULL, AIPTEK_INVALID_VALUE }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) static ssize_t show_tabletCoordinateMode(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) struct aiptek *aiptek = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) return snprintf(buf, PAGE_SIZE, "%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) map_val_to_str(coordinate_mode_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) aiptek->curSetting.coordinateMode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) store_tabletCoordinateMode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) struct aiptek *aiptek = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) int new_mode = map_str_to_val(coordinate_mode_map, buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) if (new_mode == AIPTEK_INVALID_VALUE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) aiptek->newSetting.coordinateMode = new_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) static DEVICE_ATTR(coordinate_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) show_tabletCoordinateMode, store_tabletCoordinateMode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) /***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) * support routines for the 'tool_mode' file. Note that this file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) * both displays current setting and allows reprogramming.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) static struct aiptek_map tool_mode_map[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) { "mouse", AIPTEK_TOOL_BUTTON_MOUSE_MODE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) { "eraser", AIPTEK_TOOL_BUTTON_ERASER_MODE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) { "pencil", AIPTEK_TOOL_BUTTON_PENCIL_MODE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) { "pen", AIPTEK_TOOL_BUTTON_PEN_MODE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) { "brush", AIPTEK_TOOL_BUTTON_BRUSH_MODE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) { "airbrush", AIPTEK_TOOL_BUTTON_AIRBRUSH_MODE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) { "lens", AIPTEK_TOOL_BUTTON_LENS_MODE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) { NULL, AIPTEK_INVALID_VALUE }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) static ssize_t show_tabletToolMode(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) struct aiptek *aiptek = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) return snprintf(buf, PAGE_SIZE, "%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) map_val_to_str(tool_mode_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) aiptek->curSetting.toolMode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) store_tabletToolMode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) struct aiptek *aiptek = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) int new_mode = map_str_to_val(tool_mode_map, buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) if (new_mode == AIPTEK_INVALID_VALUE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) aiptek->newSetting.toolMode = new_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) static DEVICE_ATTR(tool_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) show_tabletToolMode, store_tabletToolMode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) /***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) * support routines for the 'xtilt' file. Note that this file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) * both displays current setting and allows reprogramming.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) static ssize_t show_tabletXtilt(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) struct aiptek *aiptek = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) if (aiptek->curSetting.xTilt == AIPTEK_TILT_DISABLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) return snprintf(buf, PAGE_SIZE, "disable\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) return snprintf(buf, PAGE_SIZE, "%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) aiptek->curSetting.xTilt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) store_tabletXtilt(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) struct aiptek *aiptek = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) int x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) if (kstrtoint(buf, 10, &x)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) size_t len = buf[count - 1] == '\n' ? count - 1 : count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) if (strncmp(buf, "disable", len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) aiptek->newSetting.xTilt = AIPTEK_TILT_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) if (x < AIPTEK_TILT_MIN || x > AIPTEK_TILT_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) aiptek->newSetting.xTilt = x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) static DEVICE_ATTR(xtilt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) S_IRUGO | S_IWUSR, show_tabletXtilt, store_tabletXtilt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) /***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) * support routines for the 'ytilt' file. Note that this file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) * both displays current setting and allows reprogramming.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) static ssize_t show_tabletYtilt(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) struct aiptek *aiptek = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) if (aiptek->curSetting.yTilt == AIPTEK_TILT_DISABLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) return snprintf(buf, PAGE_SIZE, "disable\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) return snprintf(buf, PAGE_SIZE, "%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) aiptek->curSetting.yTilt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) store_tabletYtilt(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) struct aiptek *aiptek = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) int y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) if (kstrtoint(buf, 10, &y)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) size_t len = buf[count - 1] == '\n' ? count - 1 : count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) if (strncmp(buf, "disable", len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) aiptek->newSetting.yTilt = AIPTEK_TILT_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) if (y < AIPTEK_TILT_MIN || y > AIPTEK_TILT_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) aiptek->newSetting.yTilt = y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) static DEVICE_ATTR(ytilt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) S_IRUGO | S_IWUSR, show_tabletYtilt, store_tabletYtilt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) /***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) * support routines for the 'jitter' file. Note that this file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) * both displays current setting and allows reprogramming.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) static ssize_t show_tabletJitterDelay(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) struct aiptek *aiptek = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) return snprintf(buf, PAGE_SIZE, "%d\n", aiptek->curSetting.jitterDelay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) store_tabletJitterDelay(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) struct aiptek *aiptek = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) int err, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) err = kstrtoint(buf, 10, &j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) aiptek->newSetting.jitterDelay = j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) static DEVICE_ATTR(jitter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) show_tabletJitterDelay, store_tabletJitterDelay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) /***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) * support routines for the 'delay' file. Note that this file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) * both displays current setting and allows reprogramming.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) static ssize_t show_tabletProgrammableDelay(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) struct aiptek *aiptek = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) return snprintf(buf, PAGE_SIZE, "%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) aiptek->curSetting.programmableDelay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) store_tabletProgrammableDelay(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) struct aiptek *aiptek = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) int err, d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) err = kstrtoint(buf, 10, &d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) aiptek->newSetting.programmableDelay = d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) static DEVICE_ATTR(delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) show_tabletProgrammableDelay, store_tabletProgrammableDelay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) /***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) * support routines for the 'event_count' file. Note that this file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) * only displays current setting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) static ssize_t show_tabletEventsReceived(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) struct aiptek *aiptek = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) return snprintf(buf, PAGE_SIZE, "%ld\n", aiptek->eventCount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) static DEVICE_ATTR(event_count, S_IRUGO, show_tabletEventsReceived, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) /***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) * support routines for the 'diagnostic' file. Note that this file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) * only displays current setting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) static ssize_t show_tabletDiagnosticMessage(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) struct aiptek *aiptek = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) char *retMsg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) switch (aiptek->diagnostic) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) case AIPTEK_DIAGNOSTIC_NA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) retMsg = "no errors\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) case AIPTEK_DIAGNOSTIC_SENDING_RELATIVE_IN_ABSOLUTE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) retMsg = "Error: receiving relative reports\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) case AIPTEK_DIAGNOSTIC_SENDING_ABSOLUTE_IN_RELATIVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) retMsg = "Error: receiving absolute reports\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) case AIPTEK_DIAGNOSTIC_TOOL_DISALLOWED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) if (aiptek->curSetting.pointerMode ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) AIPTEK_POINTER_ONLY_MOUSE_MODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) retMsg = "Error: receiving stylus reports\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) retMsg = "Error: receiving mouse reports\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) return snprintf(buf, PAGE_SIZE, retMsg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) static DEVICE_ATTR(diagnostic, S_IRUGO, show_tabletDiagnosticMessage, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) /***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) * support routines for the 'stylus_upper' file. Note that this file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) * both displays current setting and allows for setting changing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) static struct aiptek_map stylus_button_map[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) { "upper", AIPTEK_STYLUS_UPPER_BUTTON },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) { "lower", AIPTEK_STYLUS_LOWER_BUTTON },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) { NULL, AIPTEK_INVALID_VALUE }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) static ssize_t show_tabletStylusUpper(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) struct aiptek *aiptek = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) return snprintf(buf, PAGE_SIZE, "%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) map_val_to_str(stylus_button_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) aiptek->curSetting.stylusButtonUpper));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) store_tabletStylusUpper(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) struct aiptek *aiptek = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) int new_button = map_str_to_val(stylus_button_map, buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) if (new_button == AIPTEK_INVALID_VALUE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) aiptek->newSetting.stylusButtonUpper = new_button;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) static DEVICE_ATTR(stylus_upper,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) show_tabletStylusUpper, store_tabletStylusUpper);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) /***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) * support routines for the 'stylus_lower' file. Note that this file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) * both displays current setting and allows for setting changing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) static ssize_t show_tabletStylusLower(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) struct aiptek *aiptek = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) return snprintf(buf, PAGE_SIZE, "%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) map_val_to_str(stylus_button_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) aiptek->curSetting.stylusButtonLower));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) store_tabletStylusLower(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) struct aiptek *aiptek = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) int new_button = map_str_to_val(stylus_button_map, buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) if (new_button == AIPTEK_INVALID_VALUE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) aiptek->newSetting.stylusButtonLower = new_button;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) static DEVICE_ATTR(stylus_lower,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) show_tabletStylusLower, store_tabletStylusLower);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) /***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) * support routines for the 'mouse_left' file. Note that this file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) * both displays current setting and allows for setting changing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) static struct aiptek_map mouse_button_map[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) { "left", AIPTEK_MOUSE_LEFT_BUTTON },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) { "middle", AIPTEK_MOUSE_MIDDLE_BUTTON },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) { "right", AIPTEK_MOUSE_RIGHT_BUTTON },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) { NULL, AIPTEK_INVALID_VALUE }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) static ssize_t show_tabletMouseLeft(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) struct aiptek *aiptek = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) return snprintf(buf, PAGE_SIZE, "%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) map_val_to_str(mouse_button_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) aiptek->curSetting.mouseButtonLeft));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) store_tabletMouseLeft(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) struct aiptek *aiptek = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) int new_button = map_str_to_val(mouse_button_map, buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) if (new_button == AIPTEK_INVALID_VALUE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) aiptek->newSetting.mouseButtonLeft = new_button;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) static DEVICE_ATTR(mouse_left,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) show_tabletMouseLeft, store_tabletMouseLeft);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) /***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) * support routines for the 'mouse_middle' file. Note that this file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) * both displays current setting and allows for setting changing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) static ssize_t show_tabletMouseMiddle(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) struct aiptek *aiptek = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) return snprintf(buf, PAGE_SIZE, "%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) map_val_to_str(mouse_button_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) aiptek->curSetting.mouseButtonMiddle));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) store_tabletMouseMiddle(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) struct aiptek *aiptek = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) int new_button = map_str_to_val(mouse_button_map, buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) if (new_button == AIPTEK_INVALID_VALUE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) aiptek->newSetting.mouseButtonMiddle = new_button;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) static DEVICE_ATTR(mouse_middle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) show_tabletMouseMiddle, store_tabletMouseMiddle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) /***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) * support routines for the 'mouse_right' file. Note that this file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) * both displays current setting and allows for setting changing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) static ssize_t show_tabletMouseRight(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) struct aiptek *aiptek = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) return snprintf(buf, PAGE_SIZE, "%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) map_val_to_str(mouse_button_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) aiptek->curSetting.mouseButtonRight));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) store_tabletMouseRight(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) struct aiptek *aiptek = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) int new_button = map_str_to_val(mouse_button_map, buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) if (new_button == AIPTEK_INVALID_VALUE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) aiptek->newSetting.mouseButtonRight = new_button;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) static DEVICE_ATTR(mouse_right,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) show_tabletMouseRight, store_tabletMouseRight);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) /***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) * support routines for the 'wheel' file. Note that this file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) * both displays current setting and allows for setting changing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) static ssize_t show_tabletWheel(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) struct aiptek *aiptek = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) if (aiptek->curSetting.wheel == AIPTEK_WHEEL_DISABLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) return snprintf(buf, PAGE_SIZE, "disable\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) return snprintf(buf, PAGE_SIZE, "%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) aiptek->curSetting.wheel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) store_tabletWheel(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) struct aiptek *aiptek = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) int err, w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) err = kstrtoint(buf, 10, &w);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) aiptek->newSetting.wheel = w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) static DEVICE_ATTR(wheel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) S_IRUGO | S_IWUSR, show_tabletWheel, store_tabletWheel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) /***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) * support routines for the 'execute' file. Note that this file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) * both displays current setting and allows for setting changing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) static ssize_t show_tabletExecute(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) /* There is nothing useful to display, so a one-line manual
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) * is in order...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) return snprintf(buf, PAGE_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) "Write anything to this file to program your tablet.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) store_tabletExecute(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) struct aiptek *aiptek = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) /* We do not care what you write to this file. Merely the action
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) * of writing to this file triggers a tablet reprogramming.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) memcpy(&aiptek->curSetting, &aiptek->newSetting,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) sizeof(struct aiptek_settings));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) if (aiptek_program_tablet(aiptek) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) static DEVICE_ATTR(execute,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) S_IRUGO | S_IWUSR, show_tabletExecute, store_tabletExecute);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) /***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) * support routines for the 'odm_code' file. Note that this file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) * only displays current setting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) static ssize_t show_tabletODMCode(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) struct aiptek *aiptek = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) return snprintf(buf, PAGE_SIZE, "0x%04x\n", aiptek->features.odmCode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) static DEVICE_ATTR(odm_code, S_IRUGO, show_tabletODMCode, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) /***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) * support routines for the 'model_code' file. Note that this file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) * only displays current setting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) static ssize_t show_tabletModelCode(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) struct aiptek *aiptek = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) return snprintf(buf, PAGE_SIZE, "0x%04x\n", aiptek->features.modelCode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) static DEVICE_ATTR(model_code, S_IRUGO, show_tabletModelCode, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) /***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) * support routines for the 'firmware_code' file. Note that this file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) * only displays current setting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) static ssize_t show_firmwareCode(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) struct aiptek *aiptek = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) return snprintf(buf, PAGE_SIZE, "%04x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) aiptek->features.firmwareCode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) static DEVICE_ATTR(firmware_code, S_IRUGO, show_firmwareCode, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) static struct attribute *aiptek_attributes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) &dev_attr_size.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) &dev_attr_pointer_mode.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) &dev_attr_coordinate_mode.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) &dev_attr_tool_mode.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) &dev_attr_xtilt.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) &dev_attr_ytilt.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) &dev_attr_jitter.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) &dev_attr_delay.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) &dev_attr_event_count.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) &dev_attr_diagnostic.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) &dev_attr_odm_code.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) &dev_attr_model_code.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) &dev_attr_firmware_code.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) &dev_attr_stylus_lower.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) &dev_attr_stylus_upper.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) &dev_attr_mouse_left.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) &dev_attr_mouse_middle.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) &dev_attr_mouse_right.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) &dev_attr_wheel.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) &dev_attr_execute.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) static const struct attribute_group aiptek_attribute_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) .attrs = aiptek_attributes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) /***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) * This routine is called when a tablet has been identified. It basically
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) * sets up the tablet and the driver's internal structures.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) struct usb_device *usbdev = interface_to_usbdev(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) struct usb_endpoint_descriptor *endpoint;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) struct aiptek *aiptek;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) struct input_dev *inputdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) int speeds[] = { 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) AIPTEK_PROGRAMMABLE_DELAY_50,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) AIPTEK_PROGRAMMABLE_DELAY_400,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) AIPTEK_PROGRAMMABLE_DELAY_25,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) AIPTEK_PROGRAMMABLE_DELAY_100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) AIPTEK_PROGRAMMABLE_DELAY_200,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) AIPTEK_PROGRAMMABLE_DELAY_300
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) int err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) /* programmableDelay is where the command-line specified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) * delay is kept. We make it the first element of speeds[],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) * so therefore, your override speed is tried first, then the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) * remainder. Note that the default value of 400ms will be tried
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) * if you do not specify any command line parameter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) speeds[0] = programmableDelay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) aiptek = kzalloc(sizeof(struct aiptek), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) inputdev = input_allocate_device();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) if (!aiptek || !inputdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) dev_warn(&intf->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) "cannot allocate memory or input device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) goto fail1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) aiptek->data = usb_alloc_coherent(usbdev, AIPTEK_PACKET_LENGTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) GFP_KERNEL, &aiptek->data_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) if (!aiptek->data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) dev_warn(&intf->dev, "cannot allocate usb buffer\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) goto fail1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) aiptek->urb = usb_alloc_urb(0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) if (!aiptek->urb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) dev_warn(&intf->dev, "cannot allocate urb\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) goto fail2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) aiptek->inputdev = inputdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) aiptek->intf = intf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) aiptek->ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) aiptek->inDelay = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) aiptek->endDelay = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) aiptek->previousJitterable = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) aiptek->lastMacro = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) /* Set up the curSettings struct. Said struct contains the current
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) * programmable parameters. The newSetting struct contains changes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) * the user makes to the settings via the sysfs interface. Those
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) * changes are not "committed" to curSettings until the user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) * writes to the sysfs/.../execute file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) aiptek->curSetting.pointerMode = AIPTEK_POINTER_EITHER_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) aiptek->curSetting.coordinateMode = AIPTEK_COORDINATE_ABSOLUTE_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) aiptek->curSetting.toolMode = AIPTEK_TOOL_BUTTON_PEN_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) aiptek->curSetting.xTilt = AIPTEK_TILT_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) aiptek->curSetting.yTilt = AIPTEK_TILT_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) aiptek->curSetting.mouseButtonLeft = AIPTEK_MOUSE_LEFT_BUTTON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) aiptek->curSetting.mouseButtonMiddle = AIPTEK_MOUSE_MIDDLE_BUTTON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) aiptek->curSetting.mouseButtonRight = AIPTEK_MOUSE_RIGHT_BUTTON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) aiptek->curSetting.stylusButtonUpper = AIPTEK_STYLUS_UPPER_BUTTON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) aiptek->curSetting.stylusButtonLower = AIPTEK_STYLUS_LOWER_BUTTON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) aiptek->curSetting.jitterDelay = jitterDelay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) aiptek->curSetting.programmableDelay = programmableDelay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) /* Both structs should have equivalent settings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) aiptek->newSetting = aiptek->curSetting;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) /* Determine the usb devices' physical path.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) * Asketh not why we always pretend we're using "../input0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) * but I suspect this will have to be refactored one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) * day if a single USB device can be a keyboard & a mouse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) * & a tablet, and the inputX number actually will tell
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) * us something...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) usb_make_path(usbdev, aiptek->features.usbPath,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) sizeof(aiptek->features.usbPath));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) strlcat(aiptek->features.usbPath, "/input0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) sizeof(aiptek->features.usbPath));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) /* Set up client data, pointers to open and close routines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) * for the input device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) inputdev->name = "Aiptek";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) inputdev->phys = aiptek->features.usbPath;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) usb_to_input_id(usbdev, &inputdev->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) inputdev->dev.parent = &intf->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) input_set_drvdata(inputdev, aiptek);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) inputdev->open = aiptek_open;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) inputdev->close = aiptek_close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) /* Now program the capacities of the tablet, in terms of being
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) * an input device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) for (i = 0; i < ARRAY_SIZE(eventTypes); ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) __set_bit(eventTypes[i], inputdev->evbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) for (i = 0; i < ARRAY_SIZE(absEvents); ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) __set_bit(absEvents[i], inputdev->absbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) for (i = 0; i < ARRAY_SIZE(relEvents); ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) __set_bit(relEvents[i], inputdev->relbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) __set_bit(MSC_SERIAL, inputdev->mscbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) /* Set up key and button codes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) for (i = 0; i < ARRAY_SIZE(buttonEvents); ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) __set_bit(buttonEvents[i], inputdev->keybit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) for (i = 0; i < ARRAY_SIZE(macroKeyEvents); ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) __set_bit(macroKeyEvents[i], inputdev->keybit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) * Program the input device coordinate capacities. We do not yet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) * know what maximum X, Y, and Z values are, so we're putting fake
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) * values in. Later, we'll ask the tablet to put in the correct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) * values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) input_set_abs_params(inputdev, ABS_X, 0, 2999, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) input_set_abs_params(inputdev, ABS_Y, 0, 2249, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) input_set_abs_params(inputdev, ABS_PRESSURE, 0, 511, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) input_set_abs_params(inputdev, ABS_TILT_X, AIPTEK_TILT_MIN, AIPTEK_TILT_MAX, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) input_set_abs_params(inputdev, ABS_TILT_Y, AIPTEK_TILT_MIN, AIPTEK_TILT_MAX, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) input_set_abs_params(inputdev, ABS_WHEEL, AIPTEK_WHEEL_MIN, AIPTEK_WHEEL_MAX - 1, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) err = usb_find_common_endpoints(intf->cur_altsetting,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) NULL, NULL, &endpoint, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) dev_err(&intf->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) "interface has no int in endpoints, but must have minimum 1\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) goto fail3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) /* Go set up our URB, which is called when the tablet receives
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) * input.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) usb_fill_int_urb(aiptek->urb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) usbdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) usb_rcvintpipe(usbdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) endpoint->bEndpointAddress),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) aiptek->data, 8, aiptek_irq, aiptek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) endpoint->bInterval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) aiptek->urb->transfer_dma = aiptek->data_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) aiptek->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) /* Program the tablet. This sets the tablet up in the mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) * specified in newSetting, and also queries the tablet's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) * physical capacities.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) * Sanity check: if a tablet doesn't like the slow programmatic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) * delay, we often get sizes of 0x0. Let's use that as an indicator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) * to try faster delays, up to 25 ms. If that logic fails, well, you'll
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) * have to explain to us how your tablet thinks it's 0x0, and yet that's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) * not an error :-)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) for (i = 0; i < ARRAY_SIZE(speeds); ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) aiptek->curSetting.programmableDelay = speeds[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) (void)aiptek_program_tablet(aiptek);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) if (input_abs_get_max(aiptek->inputdev, ABS_X) > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) dev_info(&intf->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) "Aiptek using %d ms programming speed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) aiptek->curSetting.programmableDelay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) /* Murphy says that some day someone will have a tablet that fails the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) above test. That's you, Frederic Rodrigo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) if (i == ARRAY_SIZE(speeds)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) dev_info(&intf->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) "Aiptek tried all speeds, no sane response\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) goto fail3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) /* Associate this driver's struct with the usb interface.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) usb_set_intfdata(intf, aiptek);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) /* Set up the sysfs files
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) err = sysfs_create_group(&intf->dev.kobj, &aiptek_attribute_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) dev_warn(&intf->dev, "cannot create sysfs group err: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) goto fail3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) /* Register the tablet as an Input Device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) err = input_register_device(aiptek->inputdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) dev_warn(&intf->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) "input_register_device returned err: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) goto fail4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) fail4: sysfs_remove_group(&intf->dev.kobj, &aiptek_attribute_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) fail3: usb_free_urb(aiptek->urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) fail2: usb_free_coherent(usbdev, AIPTEK_PACKET_LENGTH, aiptek->data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) aiptek->data_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) fail1: usb_set_intfdata(intf, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) input_free_device(inputdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) kfree(aiptek);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) /***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) * Deal with tablet disconnecting from the system.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) static void aiptek_disconnect(struct usb_interface *intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) struct aiptek *aiptek = usb_get_intfdata(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) /* Disassociate driver's struct with usb interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) usb_set_intfdata(intf, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) if (aiptek != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) /* Free & unhook everything from the system.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) usb_kill_urb(aiptek->urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) input_unregister_device(aiptek->inputdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) sysfs_remove_group(&intf->dev.kobj, &aiptek_attribute_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) usb_free_urb(aiptek->urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) usb_free_coherent(interface_to_usbdev(intf),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) AIPTEK_PACKET_LENGTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) aiptek->data, aiptek->data_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) kfree(aiptek);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) static struct usb_driver aiptek_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) .name = "aiptek",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) .probe = aiptek_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) .disconnect = aiptek_disconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) .id_table = aiptek_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) module_usb_driver(aiptek_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) MODULE_AUTHOR("Bryan W. Headley/Chris Atenasio/Cedric Brun/Rene van Paassen");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) MODULE_DESCRIPTION("Aiptek HyperPen USB Tablet Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) module_param(programmableDelay, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) MODULE_PARM_DESC(programmableDelay, "delay used during tablet programming");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) module_param(jitterDelay, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) MODULE_PARM_DESC(jitterDelay, "stylus/mouse settlement delay");