Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1/* SPDX-License-Identifier: GPL-2.0+ */
2/*
3 * HID driver for UC-Logic devices not fully compliant with HID standard
4 * - tablet initialization and parameter retrieval
5 *
6 * Copyright (c) 2018 Nikolai Kondrashov
7 */
8
9/*
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the Free
12 * Software Foundation; either version 2 of the License, or (at your option)
13 * any later version.
14 */
15
16#ifndef _HID_UCLOGIC_PARAMS_H
17#define _HID_UCLOGIC_PARAMS_H
18
19#include <linux/usb.h>
20#include <linux/hid.h>
21
22/* Types of pen in-range reporting */
23enum uclogic_params_pen_inrange {
24 /* Normal reports: zero - out of proximity, one - in proximity */
25 UCLOGIC_PARAMS_PEN_INRANGE_NORMAL = 0,
26 /* Inverted reports: zero - in proximity, one - out of proximity */
27 UCLOGIC_PARAMS_PEN_INRANGE_INVERTED,
28 /* No reports */
29 UCLOGIC_PARAMS_PEN_INRANGE_NONE,
30};
31
32/* Convert a pen in-range reporting type to a string */
33extern const char *uclogic_params_pen_inrange_to_str(
34 enum uclogic_params_pen_inrange inrange);
35
36
37/*
38 * Pen report's subreport data.
39 */
40struct uclogic_params_pen_subreport {
41 /*
42 * The value of the second byte of the pen report indicating this
43 * subreport. If zero, the subreport should be considered invalid and
44 * not matched.
45 */
46 __u8 value;
47
48 /*
49 * The ID to be assigned to the report, if the second byte of the pen
50 * report is equal to "value". Only valid if "value" is not zero.
51 */
52 __u8 id;
53};
54
55/*
56 * Tablet interface's pen input parameters.
57 *
58 * Must use declarative (descriptive) language, not imperative, to simplify
59 * understanding and maintain consistency.
60 *
61 * Noop (preserving functionality) when filled with zeroes.
62 */
63struct uclogic_params_pen {
64 /*
65 * Pointer to report descriptor describing the inputs.
66 * Allocated with kmalloc.
67 */
68 __u8 *desc_ptr;
69 /*
70 * Size of the report descriptor.
71 * Only valid, if "desc_ptr" is not NULL.
72 */
73 unsigned int desc_size;
74 /* Report ID, if reports should be tweaked, zero if not */
75 unsigned int id;
76 /* The list of subreports */
77 struct uclogic_params_pen_subreport subreport_list[1];
78 /* Type of in-range reporting, only valid if "id" is not zero */
79 enum uclogic_params_pen_inrange inrange;
80 /*
81 * True, if reports include fragmented high resolution coords, with
82 * high-order X and then Y bytes following the pressure field.
83 * Only valid if "id" is not zero.
84 */
85 bool fragmented_hires;
86 /*
87 * True if the pen reports tilt in bytes at offset 10 (X) and 11 (Y),
88 * and the Y tilt direction is flipped.
89 * Only valid if "id" is not zero.
90 */
91 bool tilt_y_flipped;
92};
93
94/*
95 * Parameters of frame control inputs of a tablet interface.
96 *
97 * Must use declarative (descriptive) language, not imperative, to simplify
98 * understanding and maintain consistency.
99 *
100 * Noop (preserving functionality) when filled with zeroes.
101 */
102struct uclogic_params_frame {
103 /*
104 * Pointer to report descriptor describing the inputs.
105 * Allocated with kmalloc.
106 */
107 __u8 *desc_ptr;
108 /*
109 * Size of the report descriptor.
110 * Only valid, if "desc_ptr" is not NULL.
111 */
112 unsigned int desc_size;
113 /*
114 * Report ID, if reports should be tweaked, zero if not.
115 */
116 unsigned int id;
117 /*
118 * Number of the least-significant bit of the 2-bit state of a rotary
119 * encoder, in the report. Cannot point to a 2-bit field crossing a
120 * byte boundary. Zero if not present. Only valid if "id" is not zero.
121 */
122 unsigned int re_lsb;
123 /*
124 * Offset of the Wacom-style device ID byte in the report, to be set
125 * to pad device ID (0xf), for compatibility with Wacom drivers. Zero
126 * if no changes to the report should be made. Only valid if "id" is
127 * not zero.
128 */
129 unsigned int dev_id_byte;
130};
131
132/*
133 * Tablet interface report parameters.
134 *
135 * Must use declarative (descriptive) language, not imperative, to simplify
136 * understanding and maintain consistency.
137 *
138 * When filled with zeros represents a "noop" configuration - passes all
139 * reports unchanged and lets the generic HID driver handle everything.
140 *
141 * The resulting device report descriptor is assembled from all the report
142 * descriptor parts referenced by the structure. No order of assembly should
143 * be assumed. The structure represents original device report descriptor if
144 * all the parts are NULL.
145 */
146struct uclogic_params {
147 /*
148 * True if the whole interface is invalid, false otherwise.
149 */
150 bool invalid;
151 /*
152 * Pointer to the common part of the replacement report descriptor,
153 * allocated with kmalloc. NULL if no common part is needed.
154 * Only valid, if "invalid" is false.
155 */
156 __u8 *desc_ptr;
157 /*
158 * Size of the common part of the replacement report descriptor.
159 * Only valid, if "desc_ptr" is not NULL.
160 */
161 unsigned int desc_size;
162 /*
163 * Pen parameters and optional report descriptor part.
164 * Only valid, if "invalid" is false.
165 */
166 struct uclogic_params_pen pen;
167 /*
168 * The list of frame control parameters and optional report descriptor
169 * parts. Only valid, if "invalid" is false.
170 */
171 struct uclogic_params_frame frame_list[1];
172};
173
174/* Initialize a tablet interface and discover its parameters */
175extern int uclogic_params_init(struct uclogic_params *params,
176 struct hid_device *hdev);
177
178/* Tablet interface parameters *printf format string */
179#define UCLOGIC_PARAMS_FMT_STR \
180 ".invalid = %s\n" \
181 ".desc_ptr = %p\n" \
182 ".desc_size = %u\n" \
183 ".pen.desc_ptr = %p\n" \
184 ".pen.desc_size = %u\n" \
185 ".pen.id = %u\n" \
186 ".pen.subreport_list[0] = {0x%02hhx, %hhu}\n" \
187 ".pen.inrange = %s\n" \
188 ".pen.fragmented_hires = %s\n" \
189 ".pen.tilt_y_flipped = %s\n" \
190 ".frame_list[0].desc_ptr = %p\n" \
191 ".frame_list[0].desc_size = %u\n" \
192 ".frame_list[0].id = %u\n" \
193 ".frame_list[0].re_lsb = %u\n" \
194 ".frame_list[0].dev_id_byte = %u\n"
195
196/* Tablet interface parameters *printf format arguments */
197#define UCLOGIC_PARAMS_FMT_ARGS(_params) \
198 ((_params)->invalid ? "true" : "false"), \
199 (_params)->desc_ptr, \
200 (_params)->desc_size, \
201 (_params)->pen.desc_ptr, \
202 (_params)->pen.desc_size, \
203 (_params)->pen.id, \
204 (_params)->pen.subreport_list[0].value, \
205 (_params)->pen.subreport_list[0].id, \
206 uclogic_params_pen_inrange_to_str((_params)->pen.inrange), \
207 ((_params)->pen.fragmented_hires ? "true" : "false"), \
208 ((_params)->pen.tilt_y_flipped ? "true" : "false"), \
209 (_params)->frame_list[0].desc_ptr, \
210 (_params)->frame_list[0].desc_size, \
211 (_params)->frame_list[0].id, \
212 (_params)->frame_list[0].re_lsb, \
213 (_params)->frame_list[0].dev_id_byte
214
215/* Get a replacement report descriptor for a tablet's interface. */
216extern int uclogic_params_get_desc(const struct uclogic_params *params,
217 __u8 **pdesc,
218 unsigned int *psize);
219
220/* Free resources used by tablet interface's parameters */
221extern void uclogic_params_cleanup(struct uclogic_params *params);
222
223#endif /* _HID_UCLOGIC_PARAMS_H */