Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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");