1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-or-later */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * drivers/input/tablet/wacom.h
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * USB Wacom tablet support
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * Copyright (c) 2000-2004 Vojtech Pavlik <vojtech@ucw.cz>
8*4882a593Smuzhiyun * Copyright (c) 2000 Andreas Bach Aaen <abach@stofanet.dk>
9*4882a593Smuzhiyun * Copyright (c) 2000 Clifford Wolf <clifford@clifford.at>
10*4882a593Smuzhiyun * Copyright (c) 2000 Sam Mosel <sam.mosel@computer.org>
11*4882a593Smuzhiyun * Copyright (c) 2000 James E. Blair <corvus@gnu.org>
12*4882a593Smuzhiyun * Copyright (c) 2000 Daniel Egger <egger@suse.de>
13*4882a593Smuzhiyun * Copyright (c) 2001 Frederic Lepied <flepied@mandrakesoft.com>
14*4882a593Smuzhiyun * Copyright (c) 2004 Panagiotis Issaris <panagiotis.issaris@mech.kuleuven.ac.be>
15*4882a593Smuzhiyun * Copyright (c) 2002-2011 Ping Cheng <pingc@wacom.com>
16*4882a593Smuzhiyun * Copyright (c) 2014 Benjamin Tissoires <benjamin.tissoires@redhat.com>
17*4882a593Smuzhiyun *
18*4882a593Smuzhiyun * ChangeLog:
19*4882a593Smuzhiyun * v0.1 (vp) - Initial release
20*4882a593Smuzhiyun * v0.2 (aba) - Support for all buttons / combinations
21*4882a593Smuzhiyun * v0.3 (vp) - Support for Intuos added
22*4882a593Smuzhiyun * v0.4 (sm) - Support for more Intuos models, menustrip
23*4882a593Smuzhiyun * relative mode, proximity.
24*4882a593Smuzhiyun * v0.5 (vp) - Big cleanup, nifty features removed,
25*4882a593Smuzhiyun * they belong in userspace
26*4882a593Smuzhiyun * v1.8 (vp) - Submit URB only when operating, moved to CVS,
27*4882a593Smuzhiyun * use input_report_key instead of report_btn and
28*4882a593Smuzhiyun * other cleanups
29*4882a593Smuzhiyun * v1.11 (vp) - Add URB ->dev setting for new kernels
30*4882a593Smuzhiyun * v1.11 (jb) - Add support for the 4D Mouse & Lens
31*4882a593Smuzhiyun * v1.12 (de) - Add support for two more inking pen IDs
32*4882a593Smuzhiyun * v1.14 (vp) - Use new USB device id probing scheme.
33*4882a593Smuzhiyun * Fix Wacom Graphire mouse wheel
34*4882a593Smuzhiyun * v1.18 (vp) - Fix mouse wheel direction
35*4882a593Smuzhiyun * Make mouse relative
36*4882a593Smuzhiyun * v1.20 (fl) - Report tool id for Intuos devices
37*4882a593Smuzhiyun * - Multi tools support
38*4882a593Smuzhiyun * - Corrected Intuos protocol decoding (airbrush, 4D mouse, lens cursor...)
39*4882a593Smuzhiyun * - Add PL models support
40*4882a593Smuzhiyun * - Fix Wacom Graphire mouse wheel again
41*4882a593Smuzhiyun * v1.21 (vp) - Removed protocol descriptions
42*4882a593Smuzhiyun * - Added MISC_SERIAL for tool serial numbers
43*4882a593Smuzhiyun * (gb) - Identify version on module load.
44*4882a593Smuzhiyun * v1.21.1 (fl) - added Graphire2 support
45*4882a593Smuzhiyun * v1.21.2 (fl) - added Intuos2 support
46*4882a593Smuzhiyun * - added all the PL ids
47*4882a593Smuzhiyun * v1.21.3 (fl) - added another eraser id from Neil Okamoto
48*4882a593Smuzhiyun * - added smooth filter for Graphire from Peri Hankey
49*4882a593Smuzhiyun * - added PenPartner support from Olaf van Es
50*4882a593Smuzhiyun * - new tool ids from Ole Martin Bjoerndalen
51*4882a593Smuzhiyun * v1.29 (pc) - Add support for more tablets
52*4882a593Smuzhiyun * - Fix pressure reporting
53*4882a593Smuzhiyun * v1.30 (vp) - Merge 2.4 and 2.5 drivers
54*4882a593Smuzhiyun * - Since 2.5 now has input_sync(), remove MSC_SERIAL abuse
55*4882a593Smuzhiyun * - Cleanups here and there
56*4882a593Smuzhiyun * v1.30.1 (pi) - Added Graphire3 support
57*4882a593Smuzhiyun * v1.40 (pc) - Add support for several new devices, fix eraser reporting, ...
58*4882a593Smuzhiyun * v1.43 (pc) - Added support for Cintiq 21UX
59*4882a593Smuzhiyun * - Fixed a Graphire bug
60*4882a593Smuzhiyun * - Merged wacom_intuos3_irq into wacom_intuos_irq
61*4882a593Smuzhiyun * v1.44 (pc) - Added support for Graphire4, Cintiq 710, Intuos3 6x11, etc.
62*4882a593Smuzhiyun * - Report Device IDs
63*4882a593Smuzhiyun * v1.45 (pc) - Added support for DTF 521, Intuos3 12x12 and 12x19
64*4882a593Smuzhiyun * - Minor data report fix
65*4882a593Smuzhiyun * v1.46 (pc) - Split wacom.c into wacom_sys.c and wacom_wac.c,
66*4882a593Smuzhiyun * - where wacom_sys.c deals with system specific code,
67*4882a593Smuzhiyun * - and wacom_wac.c deals with Wacom specific code
68*4882a593Smuzhiyun * - Support Intuos3 4x6
69*4882a593Smuzhiyun * v1.47 (pc) - Added support for Bamboo
70*4882a593Smuzhiyun * v1.48 (pc) - Added support for Bamboo1, BambooFun, and Cintiq 12WX
71*4882a593Smuzhiyun * v1.49 (pc) - Added support for USB Tablet PC (0x90, 0x93, and 0x9A)
72*4882a593Smuzhiyun * v1.50 (pc) - Fixed a TabletPC touch bug in 2.6.28
73*4882a593Smuzhiyun * v1.51 (pc) - Added support for Intuos4
74*4882a593Smuzhiyun * v1.52 (pc) - Query Wacom data upon system resume
75*4882a593Smuzhiyun * - add defines for features->type
76*4882a593Smuzhiyun * - add new devices (0x9F, 0xE2, and 0XE3)
77*4882a593Smuzhiyun * v2.00 (bt) - conversion to a HID driver
78*4882a593Smuzhiyun * - integration of the Bluetooth devices
79*4882a593Smuzhiyun */
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun /*
82*4882a593Smuzhiyun */
83*4882a593Smuzhiyun #ifndef WACOM_H
84*4882a593Smuzhiyun #define WACOM_H
85*4882a593Smuzhiyun #include <linux/kernel.h>
86*4882a593Smuzhiyun #include <linux/slab.h>
87*4882a593Smuzhiyun #include <linux/module.h>
88*4882a593Smuzhiyun #include <linux/mod_devicetable.h>
89*4882a593Smuzhiyun #include <linux/hid.h>
90*4882a593Smuzhiyun #include <linux/kfifo.h>
91*4882a593Smuzhiyun #include <linux/leds.h>
92*4882a593Smuzhiyun #include <linux/usb/input.h>
93*4882a593Smuzhiyun #include <linux/power_supply.h>
94*4882a593Smuzhiyun #include <asm/unaligned.h>
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun /*
97*4882a593Smuzhiyun * Version Information
98*4882a593Smuzhiyun */
99*4882a593Smuzhiyun #define DRIVER_VERSION "v2.00"
100*4882a593Smuzhiyun #define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>"
101*4882a593Smuzhiyun #define DRIVER_DESC "USB Wacom tablet driver"
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun #define USB_VENDOR_ID_WACOM 0x056a
104*4882a593Smuzhiyun #define USB_VENDOR_ID_LENOVO 0x17ef
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun enum wacom_worker {
107*4882a593Smuzhiyun WACOM_WORKER_WIRELESS,
108*4882a593Smuzhiyun WACOM_WORKER_BATTERY,
109*4882a593Smuzhiyun WACOM_WORKER_REMOTE,
110*4882a593Smuzhiyun WACOM_WORKER_MODE_CHANGE,
111*4882a593Smuzhiyun };
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun struct wacom;
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun struct wacom_led {
116*4882a593Smuzhiyun struct led_classdev cdev;
117*4882a593Smuzhiyun struct led_trigger trigger;
118*4882a593Smuzhiyun struct wacom *wacom;
119*4882a593Smuzhiyun unsigned int group;
120*4882a593Smuzhiyun unsigned int id;
121*4882a593Smuzhiyun u8 llv;
122*4882a593Smuzhiyun u8 hlv;
123*4882a593Smuzhiyun bool held;
124*4882a593Smuzhiyun };
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun struct wacom_group_leds {
127*4882a593Smuzhiyun u8 select; /* status led selector (0..3) */
128*4882a593Smuzhiyun struct wacom_led *leds;
129*4882a593Smuzhiyun unsigned int count;
130*4882a593Smuzhiyun struct device *dev;
131*4882a593Smuzhiyun };
132*4882a593Smuzhiyun
133*4882a593Smuzhiyun struct wacom_battery {
134*4882a593Smuzhiyun struct wacom *wacom;
135*4882a593Smuzhiyun struct power_supply_desc bat_desc;
136*4882a593Smuzhiyun struct power_supply *battery;
137*4882a593Smuzhiyun char bat_name[WACOM_NAME_MAX];
138*4882a593Smuzhiyun int bat_status;
139*4882a593Smuzhiyun int battery_capacity;
140*4882a593Smuzhiyun int bat_charging;
141*4882a593Smuzhiyun int bat_connected;
142*4882a593Smuzhiyun int ps_connected;
143*4882a593Smuzhiyun };
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun struct wacom_remote {
146*4882a593Smuzhiyun spinlock_t remote_lock;
147*4882a593Smuzhiyun struct kfifo remote_fifo;
148*4882a593Smuzhiyun struct kobject *remote_dir;
149*4882a593Smuzhiyun struct {
150*4882a593Smuzhiyun struct attribute_group group;
151*4882a593Smuzhiyun u32 serial;
152*4882a593Smuzhiyun struct input_dev *input;
153*4882a593Smuzhiyun bool registered;
154*4882a593Smuzhiyun struct wacom_battery battery;
155*4882a593Smuzhiyun } remotes[WACOM_MAX_REMOTES];
156*4882a593Smuzhiyun };
157*4882a593Smuzhiyun
158*4882a593Smuzhiyun struct wacom {
159*4882a593Smuzhiyun struct usb_device *usbdev;
160*4882a593Smuzhiyun struct usb_interface *intf;
161*4882a593Smuzhiyun struct wacom_wac wacom_wac;
162*4882a593Smuzhiyun struct hid_device *hdev;
163*4882a593Smuzhiyun struct mutex lock;
164*4882a593Smuzhiyun struct work_struct wireless_work;
165*4882a593Smuzhiyun struct work_struct battery_work;
166*4882a593Smuzhiyun struct work_struct remote_work;
167*4882a593Smuzhiyun struct delayed_work init_work;
168*4882a593Smuzhiyun struct wacom_remote *remote;
169*4882a593Smuzhiyun struct work_struct mode_change_work;
170*4882a593Smuzhiyun bool generic_has_leds;
171*4882a593Smuzhiyun struct wacom_leds {
172*4882a593Smuzhiyun struct wacom_group_leds *groups;
173*4882a593Smuzhiyun unsigned int count;
174*4882a593Smuzhiyun u8 llv; /* status led brightness no button (1..127) */
175*4882a593Smuzhiyun u8 hlv; /* status led brightness button pressed (1..127) */
176*4882a593Smuzhiyun u8 img_lum; /* OLED matrix display brightness */
177*4882a593Smuzhiyun u8 max_llv; /* maximum brightness of LED (llv) */
178*4882a593Smuzhiyun u8 max_hlv; /* maximum brightness of LED (hlv) */
179*4882a593Smuzhiyun } led;
180*4882a593Smuzhiyun struct wacom_battery battery;
181*4882a593Smuzhiyun bool resources;
182*4882a593Smuzhiyun };
183*4882a593Smuzhiyun
wacom_schedule_work(struct wacom_wac * wacom_wac,enum wacom_worker which)184*4882a593Smuzhiyun static inline void wacom_schedule_work(struct wacom_wac *wacom_wac,
185*4882a593Smuzhiyun enum wacom_worker which)
186*4882a593Smuzhiyun {
187*4882a593Smuzhiyun struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac);
188*4882a593Smuzhiyun
189*4882a593Smuzhiyun switch (which) {
190*4882a593Smuzhiyun case WACOM_WORKER_WIRELESS:
191*4882a593Smuzhiyun schedule_work(&wacom->wireless_work);
192*4882a593Smuzhiyun break;
193*4882a593Smuzhiyun case WACOM_WORKER_BATTERY:
194*4882a593Smuzhiyun schedule_work(&wacom->battery_work);
195*4882a593Smuzhiyun break;
196*4882a593Smuzhiyun case WACOM_WORKER_REMOTE:
197*4882a593Smuzhiyun schedule_work(&wacom->remote_work);
198*4882a593Smuzhiyun break;
199*4882a593Smuzhiyun case WACOM_WORKER_MODE_CHANGE:
200*4882a593Smuzhiyun schedule_work(&wacom->mode_change_work);
201*4882a593Smuzhiyun break;
202*4882a593Smuzhiyun }
203*4882a593Smuzhiyun }
204*4882a593Smuzhiyun
205*4882a593Smuzhiyun /*
206*4882a593Smuzhiyun * Convert a signed 32-bit integer to an unsigned n-bit integer. Undoes
207*4882a593Smuzhiyun * the normally-helpful work of 'hid_snto32' for fields that use signed
208*4882a593Smuzhiyun * ranges for questionable reasons.
209*4882a593Smuzhiyun */
wacom_s32tou(s32 value,__u8 n)210*4882a593Smuzhiyun static inline __u32 wacom_s32tou(s32 value, __u8 n)
211*4882a593Smuzhiyun {
212*4882a593Smuzhiyun switch (n) {
213*4882a593Smuzhiyun case 8: return ((__u8)value);
214*4882a593Smuzhiyun case 16: return ((__u16)value);
215*4882a593Smuzhiyun case 32: return ((__u32)value);
216*4882a593Smuzhiyun }
217*4882a593Smuzhiyun return value & (1 << (n - 1)) ? value & (~(~0U << n)) : value;
218*4882a593Smuzhiyun }
219*4882a593Smuzhiyun
220*4882a593Smuzhiyun extern const struct hid_device_id wacom_ids[];
221*4882a593Smuzhiyun
222*4882a593Smuzhiyun void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len);
223*4882a593Smuzhiyun void wacom_setup_device_quirks(struct wacom *wacom);
224*4882a593Smuzhiyun int wacom_setup_pen_input_capabilities(struct input_dev *input_dev,
225*4882a593Smuzhiyun struct wacom_wac *wacom_wac);
226*4882a593Smuzhiyun int wacom_setup_touch_input_capabilities(struct input_dev *input_dev,
227*4882a593Smuzhiyun struct wacom_wac *wacom_wac);
228*4882a593Smuzhiyun int wacom_setup_pad_input_capabilities(struct input_dev *input_dev,
229*4882a593Smuzhiyun struct wacom_wac *wacom_wac);
230*4882a593Smuzhiyun void wacom_wac_usage_mapping(struct hid_device *hdev,
231*4882a593Smuzhiyun struct hid_field *field, struct hid_usage *usage);
232*4882a593Smuzhiyun void wacom_wac_event(struct hid_device *hdev, struct hid_field *field,
233*4882a593Smuzhiyun struct hid_usage *usage, __s32 value);
234*4882a593Smuzhiyun void wacom_wac_report(struct hid_device *hdev, struct hid_report *report);
235*4882a593Smuzhiyun void wacom_battery_work(struct work_struct *work);
236*4882a593Smuzhiyun enum led_brightness wacom_leds_brightness_get(struct wacom_led *led);
237*4882a593Smuzhiyun struct wacom_led *wacom_led_find(struct wacom *wacom, unsigned int group,
238*4882a593Smuzhiyun unsigned int id);
239*4882a593Smuzhiyun struct wacom_led *wacom_led_next(struct wacom *wacom, struct wacom_led *cur);
240*4882a593Smuzhiyun int wacom_equivalent_usage(int usage);
241*4882a593Smuzhiyun int wacom_initialize_leds(struct wacom *wacom);
242*4882a593Smuzhiyun #endif
243