blob: 665954d6ba57293fcfc544648db645b9d2c95b2b [file] [log] [blame]
Nikolai Kondrashov96142192019-02-10 12:13:51 +02001/* 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,
Nikolai Kondrashov01309e22019-02-10 12:13:54 +020028 /* No reports */
29 UCLOGIC_PARAMS_PEN_INRANGE_NONE,
Nikolai Kondrashov96142192019-02-10 12:13:51 +020030};
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 * Tablet interface's pen input parameters.
38 *
39 * Must use declarative (descriptive) language, not imperative, to simplify
40 * understanding and maintain consistency.
41 *
42 * Noop (preserving functionality) when filled with zeroes.
43 */
44struct uclogic_params_pen {
45 /*
46 * Pointer to report descriptor describing the inputs.
47 * Allocated with kmalloc.
48 */
49 __u8 *desc_ptr;
50 /*
51 * Size of the report descriptor.
52 * Only valid, if "desc_ptr" is not NULL.
53 */
54 unsigned int desc_size;
55 /* Report ID, if reports should be tweaked, zero if not */
56 unsigned int id;
57 /* Type of in-range reporting, only valid if "id" is not zero */
58 enum uclogic_params_pen_inrange inrange;
59};
60
61/*
62 * Parameters of frame control inputs of a tablet interface.
63 *
64 * Must use declarative (descriptive) language, not imperative, to simplify
65 * understanding and maintain consistency.
66 *
67 * Noop (preserving functionality) when filled with zeroes.
68 */
69struct uclogic_params_frame {
70 /*
71 * Pointer to report descriptor describing the inputs.
72 * Allocated with kmalloc.
73 */
74 __u8 *desc_ptr;
75 /*
76 * Size of the report descriptor.
77 * Only valid, if "desc_ptr" is not NULL.
78 */
79 unsigned int desc_size;
80 /*
81 * Report ID, if reports should be tweaked, zero if not.
82 */
83 unsigned int id;
84};
85
86/*
87 * Tablet interface report parameters.
88 *
89 * Must use declarative (descriptive) language, not imperative, to simplify
90 * understanding and maintain consistency.
91 *
92 * When filled with zeros represents a "noop" configuration - passes all
93 * reports unchanged and lets the generic HID driver handle everything.
94 *
95 * The resulting device report descriptor is assembled from all the report
96 * descriptor parts referenced by the structure. No order of assembly should
97 * be assumed. The structure represents original device report descriptor if
98 * all the parts are NULL.
99 */
100struct uclogic_params {
101 /*
102 * True if the whole interface is invalid, false otherwise.
103 */
104 bool invalid;
105 /*
106 * Pointer to the common part of the replacement report descriptor,
107 * allocated with kmalloc. NULL if no common part is needed.
108 * Only valid, if "invalid" is false.
109 */
110 __u8 *desc_ptr;
111 /*
112 * Size of the common part of the replacement report descriptor.
113 * Only valid, if "desc_ptr" is not NULL.
114 */
115 unsigned int desc_size;
116 /*
117 * True, if pen usage in report descriptor is invalid, when present.
118 * Only valid, if "invalid" is false.
119 */
120 bool pen_unused;
121 /*
122 * Pen parameters and optional report descriptor part.
123 * Only valid if "pen_unused" is valid and false.
124 */
125 struct uclogic_params_pen pen;
126 /*
127 * Frame control parameters and optional report descriptor part.
128 * Only valid, if "invalid" is false.
129 */
130 struct uclogic_params_frame frame;
131 /*
132 * Bitmask matching frame controls "sub-report" flag in the second
133 * byte of the pen report, or zero if it's not expected.
134 * Only valid if both "pen" and "frame" are valid, and "frame.id" is
135 * not zero.
136 */
137 __u8 pen_frame_flag;
138};
139
140/* Initialize a tablet interface and discover its parameters */
141extern int uclogic_params_init(struct uclogic_params *params,
142 struct hid_device *hdev);
143
144/* Tablet interface parameters *printf format string */
145#define UCLOGIC_PARAMS_FMT_STR \
146 ".invalid = %s\n" \
147 ".desc_ptr = %p\n" \
148 ".desc_size = %u\n" \
149 ".pen_unused = %s\n" \
150 ".pen.desc_ptr = %p\n" \
151 ".pen.desc_size = %u\n" \
152 ".pen.id = %u\n" \
153 ".pen.inrange = %s\n" \
154 ".frame.desc_ptr = %p\n" \
155 ".frame.desc_size = %u\n" \
156 ".frame.id = %u\n" \
157 ".pen_frame_flag = 0x%02x\n"
158
159/* Tablet interface parameters *printf format arguments */
160#define UCLOGIC_PARAMS_FMT_ARGS(_params) \
161 ((_params)->invalid ? "true" : "false"), \
162 (_params)->desc_ptr, \
163 (_params)->desc_size, \
164 ((_params)->pen_unused ? "true" : "false"), \
165 (_params)->pen.desc_ptr, \
166 (_params)->pen.desc_size, \
167 (_params)->pen.id, \
168 uclogic_params_pen_inrange_to_str((_params)->pen.inrange), \
169 (_params)->frame.desc_ptr, \
170 (_params)->frame.desc_size, \
171 (_params)->frame.id, \
172 (_params)->pen_frame_flag
173
174/* Get a replacement report descriptor for a tablet's interface. */
175extern int uclogic_params_get_desc(const struct uclogic_params *params,
176 __u8 **pdesc,
177 unsigned int *psize);
178
179/* Free resources used by tablet interface's parameters */
180extern void uclogic_params_cleanup(struct uclogic_params *params);
181
182#endif /* _HID_UCLOGIC_PARAMS_H */