| 1 | // SPDX-License-Identifier: GPL-2.0-or-later | 
|---|
| 2 | /* | 
|---|
| 3 | *  HID driver for N-Trig touchscreens | 
|---|
| 4 | * | 
|---|
| 5 | *  Copyright (c) 2008-2010 Rafi Rubin | 
|---|
| 6 | *  Copyright (c) 2009-2010 Stephane Chatty | 
|---|
| 7 | */ | 
|---|
| 8 |  | 
|---|
| 9 | /* | 
|---|
| 10 | */ | 
|---|
| 11 |  | 
|---|
| 12 | #include <linux/device.h> | 
|---|
| 13 | #include <linux/hid.h> | 
|---|
| 14 | #include <linux/usb.h> | 
|---|
| 15 | #include "usbhid/usbhid.h" | 
|---|
| 16 | #include <linux/module.h> | 
|---|
| 17 | #include <linux/slab.h> | 
|---|
| 18 |  | 
|---|
| 19 | #include "hid-ids.h" | 
|---|
| 20 |  | 
|---|
| 21 | #define NTRIG_DUPLICATE_USAGES	0x001 | 
|---|
| 22 |  | 
|---|
| 23 | static unsigned int min_width; | 
|---|
| 24 | module_param(min_width, uint, 0644); | 
|---|
| 25 | MODULE_PARM_DESC(min_width, "Minimum touch contact width to accept."); | 
|---|
| 26 |  | 
|---|
| 27 | static unsigned int min_height; | 
|---|
| 28 | module_param(min_height, uint, 0644); | 
|---|
| 29 | MODULE_PARM_DESC(min_height, "Minimum touch contact height to accept."); | 
|---|
| 30 |  | 
|---|
| 31 | static unsigned int activate_slack = 1; | 
|---|
| 32 | module_param(activate_slack, uint, 0644); | 
|---|
| 33 | MODULE_PARM_DESC(activate_slack, "Number of touch frames to ignore at " | 
|---|
| 34 | "the start of touch input."); | 
|---|
| 35 |  | 
|---|
| 36 | static unsigned int deactivate_slack = 4; | 
|---|
| 37 | module_param(deactivate_slack, uint, 0644); | 
|---|
| 38 | MODULE_PARM_DESC(deactivate_slack, "Number of empty frames to ignore before " | 
|---|
| 39 | "deactivating touch."); | 
|---|
| 40 |  | 
|---|
| 41 | static unsigned int activation_width = 64; | 
|---|
| 42 | module_param(activation_width, uint, 0644); | 
|---|
| 43 | MODULE_PARM_DESC(activation_width, "Width threshold to immediately start " | 
|---|
| 44 | "processing touch events."); | 
|---|
| 45 |  | 
|---|
| 46 | static unsigned int activation_height = 32; | 
|---|
| 47 | module_param(activation_height, uint, 0644); | 
|---|
| 48 | MODULE_PARM_DESC(activation_height, "Height threshold to immediately start " | 
|---|
| 49 | "processing touch events."); | 
|---|
| 50 |  | 
|---|
| 51 | struct ntrig_data { | 
|---|
| 52 | /* Incoming raw values for a single contact */ | 
|---|
| 53 | __u16 x, y, w, h; | 
|---|
| 54 | __u16 id; | 
|---|
| 55 |  | 
|---|
| 56 | bool tipswitch; | 
|---|
| 57 | bool confidence; | 
|---|
| 58 | bool first_contact_touch; | 
|---|
| 59 |  | 
|---|
| 60 | bool reading_mt; | 
|---|
| 61 |  | 
|---|
| 62 | __u8 [4]; | 
|---|
| 63 | __u8 ; | 
|---|
| 64 |  | 
|---|
| 65 | /* The current activation state. */ | 
|---|
| 66 | __s8 act_state; | 
|---|
| 67 |  | 
|---|
| 68 | /* Empty frames to ignore before recognizing the end of activity */ | 
|---|
| 69 | __s8 deactivate_slack; | 
|---|
| 70 |  | 
|---|
| 71 | /* Frames to ignore before acknowledging the start of activity */ | 
|---|
| 72 | __s8 activate_slack; | 
|---|
| 73 |  | 
|---|
| 74 | /* Minimum size contact to accept */ | 
|---|
| 75 | __u16 min_width; | 
|---|
| 76 | __u16 min_height; | 
|---|
| 77 |  | 
|---|
| 78 | /* Threshold to override activation slack */ | 
|---|
| 79 | __u16 activation_width; | 
|---|
| 80 | __u16 activation_height; | 
|---|
| 81 |  | 
|---|
| 82 | __u16 sensor_logical_width; | 
|---|
| 83 | __u16 sensor_logical_height; | 
|---|
| 84 | __u16 sensor_physical_width; | 
|---|
| 85 | __u16 sensor_physical_height; | 
|---|
| 86 | }; | 
|---|
| 87 |  | 
|---|
| 88 |  | 
|---|
| 89 | /* | 
|---|
| 90 | * This function converts the 4 byte raw firmware code into | 
|---|
| 91 | * a string containing 5 comma separated numbers. | 
|---|
| 92 | */ | 
|---|
| 93 | static int ntrig_version_string(unsigned char *raw, char *buf) | 
|---|
| 94 | { | 
|---|
| 95 | __u8 a =  (raw[1] & 0x0e) >> 1; | 
|---|
| 96 | __u8 b =  (raw[0] & 0x3c) >> 2; | 
|---|
| 97 | __u8 c = ((raw[0] & 0x03) << 3) | ((raw[3] & 0xe0) >> 5); | 
|---|
| 98 | __u8 d = ((raw[3] & 0x07) << 3) | ((raw[2] & 0xe0) >> 5); | 
|---|
| 99 | __u8 e =   raw[2] & 0x07; | 
|---|
| 100 |  | 
|---|
| 101 | /* | 
|---|
| 102 | * As yet unmapped bits: | 
|---|
| 103 | * 0b11000000 0b11110001 0b00011000 0b00011000 | 
|---|
| 104 | */ | 
|---|
| 105 |  | 
|---|
| 106 | return sprintf(buf, fmt: "%u.%u.%u.%u.%u", a, b, c, d, e); | 
|---|
| 107 | } | 
|---|
| 108 |  | 
|---|
| 109 | static inline int ntrig_get_mode(struct hid_device *hdev) | 
|---|
| 110 | { | 
|---|
| 111 | struct hid_report *report = hdev->report_enum[HID_FEATURE_REPORT]. | 
|---|
| 112 | report_id_hash[0x0d]; | 
|---|
| 113 |  | 
|---|
| 114 | if (!report || report->maxfield < 1 || | 
|---|
| 115 | report->field[0]->report_count < 1) | 
|---|
| 116 | return -EINVAL; | 
|---|
| 117 |  | 
|---|
| 118 | hid_hw_request(hdev, report, reqtype: HID_REQ_GET_REPORT); | 
|---|
| 119 | hid_hw_wait(hdev); | 
|---|
| 120 | return (int)report->field[0]->value[0]; | 
|---|
| 121 | } | 
|---|
| 122 |  | 
|---|
| 123 | static inline void ntrig_set_mode(struct hid_device *hdev, const int mode) | 
|---|
| 124 | { | 
|---|
| 125 | struct hid_report *report; | 
|---|
| 126 | __u8 mode_commands[4] = { 0xe, 0xf, 0x1b, 0x10 }; | 
|---|
| 127 |  | 
|---|
| 128 | if (mode < 0 || mode > 3) | 
|---|
| 129 | return; | 
|---|
| 130 |  | 
|---|
| 131 | report = hdev->report_enum[HID_FEATURE_REPORT]. | 
|---|
| 132 | report_id_hash[mode_commands[mode]]; | 
|---|
| 133 |  | 
|---|
| 134 | if (!report) | 
|---|
| 135 | return; | 
|---|
| 136 |  | 
|---|
| 137 | hid_hw_request(hdev, report, reqtype: HID_REQ_GET_REPORT); | 
|---|
| 138 | } | 
|---|
| 139 |  | 
|---|
| 140 | static void ntrig_report_version(struct hid_device *hdev) | 
|---|
| 141 | { | 
|---|
| 142 | int ret; | 
|---|
| 143 | char buf[20]; | 
|---|
| 144 | struct usb_device *usb_dev = hid_to_usb_dev(hdev); | 
|---|
| 145 | unsigned char *data = kmalloc(8, GFP_KERNEL); | 
|---|
| 146 |  | 
|---|
| 147 | if (!hid_is_usb(hdev)) | 
|---|
| 148 | return; | 
|---|
| 149 |  | 
|---|
| 150 | if (!data) | 
|---|
| 151 | goto err_free; | 
|---|
| 152 |  | 
|---|
| 153 | ret = usb_control_msg(dev: usb_dev, usb_rcvctrlpipe(usb_dev, 0), | 
|---|
| 154 | USB_REQ_CLEAR_FEATURE, | 
|---|
| 155 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | | 
|---|
| 156 | USB_DIR_IN, | 
|---|
| 157 | value: 0x30c, index: 1, data, size: 8, | 
|---|
| 158 | USB_CTRL_SET_TIMEOUT); | 
|---|
| 159 |  | 
|---|
| 160 | if (ret == 8) { | 
|---|
| 161 | ret = ntrig_version_string(raw: &data[2], buf); | 
|---|
| 162 |  | 
|---|
| 163 | hid_info(hdev, "Firmware version: %s (%02x%02x %02x%02x)\n", | 
|---|
| 164 | buf, data[2], data[3], data[4], data[5]); | 
|---|
| 165 | } | 
|---|
| 166 |  | 
|---|
| 167 | err_free: | 
|---|
| 168 | kfree(objp: data); | 
|---|
| 169 | } | 
|---|
| 170 |  | 
|---|
| 171 | static ssize_t show_phys_width(struct device *dev, | 
|---|
| 172 | struct device_attribute *attr, | 
|---|
| 173 | char *buf) | 
|---|
| 174 | { | 
|---|
| 175 | struct hid_device *hdev = to_hid_device(dev); | 
|---|
| 176 | struct ntrig_data *nd = hid_get_drvdata(hdev); | 
|---|
| 177 |  | 
|---|
| 178 | return sprintf(buf, fmt: "%d\n", nd->sensor_physical_width); | 
|---|
| 179 | } | 
|---|
| 180 |  | 
|---|
| 181 | static DEVICE_ATTR(sensor_physical_width, S_IRUGO, show_phys_width, NULL); | 
|---|
| 182 |  | 
|---|
| 183 | static ssize_t show_phys_height(struct device *dev, | 
|---|
| 184 | struct device_attribute *attr, | 
|---|
| 185 | char *buf) | 
|---|
| 186 | { | 
|---|
| 187 | struct hid_device *hdev = to_hid_device(dev); | 
|---|
| 188 | struct ntrig_data *nd = hid_get_drvdata(hdev); | 
|---|
| 189 |  | 
|---|
| 190 | return sprintf(buf, fmt: "%d\n", nd->sensor_physical_height); | 
|---|
| 191 | } | 
|---|
| 192 |  | 
|---|
| 193 | static DEVICE_ATTR(sensor_physical_height, S_IRUGO, show_phys_height, NULL); | 
|---|
| 194 |  | 
|---|
| 195 | static ssize_t show_log_width(struct device *dev, | 
|---|
| 196 | struct device_attribute *attr, | 
|---|
| 197 | char *buf) | 
|---|
| 198 | { | 
|---|
| 199 | struct hid_device *hdev = to_hid_device(dev); | 
|---|
| 200 | struct ntrig_data *nd = hid_get_drvdata(hdev); | 
|---|
| 201 |  | 
|---|
| 202 | return sprintf(buf, fmt: "%d\n", nd->sensor_logical_width); | 
|---|
| 203 | } | 
|---|
| 204 |  | 
|---|
| 205 | static DEVICE_ATTR(sensor_logical_width, S_IRUGO, show_log_width, NULL); | 
|---|
| 206 |  | 
|---|
| 207 | static ssize_t show_log_height(struct device *dev, | 
|---|
| 208 | struct device_attribute *attr, | 
|---|
| 209 | char *buf) | 
|---|
| 210 | { | 
|---|
| 211 | struct hid_device *hdev = to_hid_device(dev); | 
|---|
| 212 | struct ntrig_data *nd = hid_get_drvdata(hdev); | 
|---|
| 213 |  | 
|---|
| 214 | return sprintf(buf, fmt: "%d\n", nd->sensor_logical_height); | 
|---|
| 215 | } | 
|---|
| 216 |  | 
|---|
| 217 | static DEVICE_ATTR(sensor_logical_height, S_IRUGO, show_log_height, NULL); | 
|---|
| 218 |  | 
|---|
| 219 | static ssize_t show_min_width(struct device *dev, | 
|---|
| 220 | struct device_attribute *attr, | 
|---|
| 221 | char *buf) | 
|---|
| 222 | { | 
|---|
| 223 | struct hid_device *hdev = to_hid_device(dev); | 
|---|
| 224 | struct ntrig_data *nd = hid_get_drvdata(hdev); | 
|---|
| 225 |  | 
|---|
| 226 | return sprintf(buf, fmt: "%d\n", nd->min_width * | 
|---|
| 227 | nd->sensor_physical_width / | 
|---|
| 228 | nd->sensor_logical_width); | 
|---|
| 229 | } | 
|---|
| 230 |  | 
|---|
| 231 | static ssize_t set_min_width(struct device *dev, | 
|---|
| 232 | struct device_attribute *attr, | 
|---|
| 233 | const char *buf, size_t count) | 
|---|
| 234 | { | 
|---|
| 235 | struct hid_device *hdev = to_hid_device(dev); | 
|---|
| 236 | struct ntrig_data *nd = hid_get_drvdata(hdev); | 
|---|
| 237 |  | 
|---|
| 238 | unsigned long val; | 
|---|
| 239 |  | 
|---|
| 240 | if (kstrtoul(s: buf, base: 0, res: &val)) | 
|---|
| 241 | return -EINVAL; | 
|---|
| 242 |  | 
|---|
| 243 | if (val > nd->sensor_physical_width) | 
|---|
| 244 | return -EINVAL; | 
|---|
| 245 |  | 
|---|
| 246 | nd->min_width = val * nd->sensor_logical_width / | 
|---|
| 247 | nd->sensor_physical_width; | 
|---|
| 248 |  | 
|---|
| 249 | return count; | 
|---|
| 250 | } | 
|---|
| 251 |  | 
|---|
| 252 | static DEVICE_ATTR(min_width, S_IWUSR | S_IRUGO, show_min_width, set_min_width); | 
|---|
| 253 |  | 
|---|
| 254 | static ssize_t show_min_height(struct device *dev, | 
|---|
| 255 | struct device_attribute *attr, | 
|---|
| 256 | char *buf) | 
|---|
| 257 | { | 
|---|
| 258 | struct hid_device *hdev = to_hid_device(dev); | 
|---|
| 259 | struct ntrig_data *nd = hid_get_drvdata(hdev); | 
|---|
| 260 |  | 
|---|
| 261 | return sprintf(buf, fmt: "%d\n", nd->min_height * | 
|---|
| 262 | nd->sensor_physical_height / | 
|---|
| 263 | nd->sensor_logical_height); | 
|---|
| 264 | } | 
|---|
| 265 |  | 
|---|
| 266 | static ssize_t set_min_height(struct device *dev, | 
|---|
| 267 | struct device_attribute *attr, | 
|---|
| 268 | const char *buf, size_t count) | 
|---|
| 269 | { | 
|---|
| 270 | struct hid_device *hdev = to_hid_device(dev); | 
|---|
| 271 | struct ntrig_data *nd = hid_get_drvdata(hdev); | 
|---|
| 272 |  | 
|---|
| 273 | unsigned long val; | 
|---|
| 274 |  | 
|---|
| 275 | if (kstrtoul(s: buf, base: 0, res: &val)) | 
|---|
| 276 | return -EINVAL; | 
|---|
| 277 |  | 
|---|
| 278 | if (val > nd->sensor_physical_height) | 
|---|
| 279 | return -EINVAL; | 
|---|
| 280 |  | 
|---|
| 281 | nd->min_height = val * nd->sensor_logical_height / | 
|---|
| 282 | nd->sensor_physical_height; | 
|---|
| 283 |  | 
|---|
| 284 | return count; | 
|---|
| 285 | } | 
|---|
| 286 |  | 
|---|
| 287 | static DEVICE_ATTR(min_height, S_IWUSR | S_IRUGO, show_min_height, | 
|---|
| 288 | set_min_height); | 
|---|
| 289 |  | 
|---|
| 290 | static ssize_t show_activate_slack(struct device *dev, | 
|---|
| 291 | struct device_attribute *attr, | 
|---|
| 292 | char *buf) | 
|---|
| 293 | { | 
|---|
| 294 | struct hid_device *hdev = to_hid_device(dev); | 
|---|
| 295 | struct ntrig_data *nd = hid_get_drvdata(hdev); | 
|---|
| 296 |  | 
|---|
| 297 | return sprintf(buf, fmt: "%d\n", nd->activate_slack); | 
|---|
| 298 | } | 
|---|
| 299 |  | 
|---|
| 300 | static ssize_t set_activate_slack(struct device *dev, | 
|---|
| 301 | struct device_attribute *attr, | 
|---|
| 302 | const char *buf, size_t count) | 
|---|
| 303 | { | 
|---|
| 304 | struct hid_device *hdev = to_hid_device(dev); | 
|---|
| 305 | struct ntrig_data *nd = hid_get_drvdata(hdev); | 
|---|
| 306 |  | 
|---|
| 307 | unsigned long val; | 
|---|
| 308 |  | 
|---|
| 309 | if (kstrtoul(s: buf, base: 0, res: &val)) | 
|---|
| 310 | return -EINVAL; | 
|---|
| 311 |  | 
|---|
| 312 | if (val > 0x7f) | 
|---|
| 313 | return -EINVAL; | 
|---|
| 314 |  | 
|---|
| 315 | nd->activate_slack = val; | 
|---|
| 316 |  | 
|---|
| 317 | return count; | 
|---|
| 318 | } | 
|---|
| 319 |  | 
|---|
| 320 | static DEVICE_ATTR(activate_slack, S_IWUSR | S_IRUGO, show_activate_slack, | 
|---|
| 321 | set_activate_slack); | 
|---|
| 322 |  | 
|---|
| 323 | static ssize_t show_activation_width(struct device *dev, | 
|---|
| 324 | struct device_attribute *attr, | 
|---|
| 325 | char *buf) | 
|---|
| 326 | { | 
|---|
| 327 | struct hid_device *hdev = to_hid_device(dev); | 
|---|
| 328 | struct ntrig_data *nd = hid_get_drvdata(hdev); | 
|---|
| 329 |  | 
|---|
| 330 | return sprintf(buf, fmt: "%d\n", nd->activation_width * | 
|---|
| 331 | nd->sensor_physical_width / | 
|---|
| 332 | nd->sensor_logical_width); | 
|---|
| 333 | } | 
|---|
| 334 |  | 
|---|
| 335 | static ssize_t set_activation_width(struct device *dev, | 
|---|
| 336 | struct device_attribute *attr, | 
|---|
| 337 | const char *buf, size_t count) | 
|---|
| 338 | { | 
|---|
| 339 | struct hid_device *hdev = to_hid_device(dev); | 
|---|
| 340 | struct ntrig_data *nd = hid_get_drvdata(hdev); | 
|---|
| 341 |  | 
|---|
| 342 | unsigned long val; | 
|---|
| 343 |  | 
|---|
| 344 | if (kstrtoul(s: buf, base: 0, res: &val)) | 
|---|
| 345 | return -EINVAL; | 
|---|
| 346 |  | 
|---|
| 347 | if (val > nd->sensor_physical_width) | 
|---|
| 348 | return -EINVAL; | 
|---|
| 349 |  | 
|---|
| 350 | nd->activation_width = val * nd->sensor_logical_width / | 
|---|
| 351 | nd->sensor_physical_width; | 
|---|
| 352 |  | 
|---|
| 353 | return count; | 
|---|
| 354 | } | 
|---|
| 355 |  | 
|---|
| 356 | static DEVICE_ATTR(activation_width, S_IWUSR | S_IRUGO, show_activation_width, | 
|---|
| 357 | set_activation_width); | 
|---|
| 358 |  | 
|---|
| 359 | static ssize_t show_activation_height(struct device *dev, | 
|---|
| 360 | struct device_attribute *attr, | 
|---|
| 361 | char *buf) | 
|---|
| 362 | { | 
|---|
| 363 | struct hid_device *hdev = to_hid_device(dev); | 
|---|
| 364 | struct ntrig_data *nd = hid_get_drvdata(hdev); | 
|---|
| 365 |  | 
|---|
| 366 | return sprintf(buf, fmt: "%d\n", nd->activation_height * | 
|---|
| 367 | nd->sensor_physical_height / | 
|---|
| 368 | nd->sensor_logical_height); | 
|---|
| 369 | } | 
|---|
| 370 |  | 
|---|
| 371 | static ssize_t set_activation_height(struct device *dev, | 
|---|
| 372 | struct device_attribute *attr, | 
|---|
| 373 | const char *buf, size_t count) | 
|---|
| 374 | { | 
|---|
| 375 | struct hid_device *hdev = to_hid_device(dev); | 
|---|
| 376 | struct ntrig_data *nd = hid_get_drvdata(hdev); | 
|---|
| 377 |  | 
|---|
| 378 | unsigned long val; | 
|---|
| 379 |  | 
|---|
| 380 | if (kstrtoul(s: buf, base: 0, res: &val)) | 
|---|
| 381 | return -EINVAL; | 
|---|
| 382 |  | 
|---|
| 383 | if (val > nd->sensor_physical_height) | 
|---|
| 384 | return -EINVAL; | 
|---|
| 385 |  | 
|---|
| 386 | nd->activation_height = val * nd->sensor_logical_height / | 
|---|
| 387 | nd->sensor_physical_height; | 
|---|
| 388 |  | 
|---|
| 389 | return count; | 
|---|
| 390 | } | 
|---|
| 391 |  | 
|---|
| 392 | static DEVICE_ATTR(activation_height, S_IWUSR | S_IRUGO, | 
|---|
| 393 | show_activation_height, set_activation_height); | 
|---|
| 394 |  | 
|---|
| 395 | static ssize_t show_deactivate_slack(struct device *dev, | 
|---|
| 396 | struct device_attribute *attr, | 
|---|
| 397 | char *buf) | 
|---|
| 398 | { | 
|---|
| 399 | struct hid_device *hdev = to_hid_device(dev); | 
|---|
| 400 | struct ntrig_data *nd = hid_get_drvdata(hdev); | 
|---|
| 401 |  | 
|---|
| 402 | return sprintf(buf, fmt: "%d\n", -nd->deactivate_slack); | 
|---|
| 403 | } | 
|---|
| 404 |  | 
|---|
| 405 | static ssize_t set_deactivate_slack(struct device *dev, | 
|---|
| 406 | struct device_attribute *attr, | 
|---|
| 407 | const char *buf, size_t count) | 
|---|
| 408 | { | 
|---|
| 409 | struct hid_device *hdev = to_hid_device(dev); | 
|---|
| 410 | struct ntrig_data *nd = hid_get_drvdata(hdev); | 
|---|
| 411 |  | 
|---|
| 412 | unsigned long val; | 
|---|
| 413 |  | 
|---|
| 414 | if (kstrtoul(s: buf, base: 0, res: &val)) | 
|---|
| 415 | return -EINVAL; | 
|---|
| 416 |  | 
|---|
| 417 | /* | 
|---|
| 418 | * No more than 8 terminal frames have been observed so far | 
|---|
| 419 | * and higher slack is highly likely to leave the single | 
|---|
| 420 | * touch emulation stuck down. | 
|---|
| 421 | */ | 
|---|
| 422 | if (val > 7) | 
|---|
| 423 | return -EINVAL; | 
|---|
| 424 |  | 
|---|
| 425 | nd->deactivate_slack = -val; | 
|---|
| 426 |  | 
|---|
| 427 | return count; | 
|---|
| 428 | } | 
|---|
| 429 |  | 
|---|
| 430 | static DEVICE_ATTR(deactivate_slack, S_IWUSR | S_IRUGO, show_deactivate_slack, | 
|---|
| 431 | set_deactivate_slack); | 
|---|
| 432 |  | 
|---|
| 433 | static struct attribute *sysfs_attrs[] = { | 
|---|
| 434 | &dev_attr_sensor_physical_width.attr, | 
|---|
| 435 | &dev_attr_sensor_physical_height.attr, | 
|---|
| 436 | &dev_attr_sensor_logical_width.attr, | 
|---|
| 437 | &dev_attr_sensor_logical_height.attr, | 
|---|
| 438 | &dev_attr_min_height.attr, | 
|---|
| 439 | &dev_attr_min_width.attr, | 
|---|
| 440 | &dev_attr_activate_slack.attr, | 
|---|
| 441 | &dev_attr_activation_width.attr, | 
|---|
| 442 | &dev_attr_activation_height.attr, | 
|---|
| 443 | &dev_attr_deactivate_slack.attr, | 
|---|
| 444 | NULL | 
|---|
| 445 | }; | 
|---|
| 446 |  | 
|---|
| 447 | static const struct attribute_group ntrig_attribute_group = { | 
|---|
| 448 | .attrs = sysfs_attrs | 
|---|
| 449 | }; | 
|---|
| 450 |  | 
|---|
| 451 | /* | 
|---|
| 452 | * this driver is aimed at two firmware versions in circulation: | 
|---|
| 453 | *  - dual pen/finger single touch | 
|---|
| 454 | *  - finger multitouch, pen not working | 
|---|
| 455 | */ | 
|---|
| 456 |  | 
|---|
| 457 | static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi, | 
|---|
| 458 | struct hid_field *field, struct hid_usage *usage, | 
|---|
| 459 | unsigned long **bit, int *max) | 
|---|
| 460 | { | 
|---|
| 461 | struct ntrig_data *nd = hid_get_drvdata(hdev); | 
|---|
| 462 |  | 
|---|
| 463 | /* No special mappings needed for the pen and single touch */ | 
|---|
| 464 | if (field->physical) | 
|---|
| 465 | return 0; | 
|---|
| 466 |  | 
|---|
| 467 | switch (usage->hid & HID_USAGE_PAGE) { | 
|---|
| 468 | case HID_UP_GENDESK: | 
|---|
| 469 | switch (usage->hid) { | 
|---|
| 470 | case HID_GD_X: | 
|---|
| 471 | hid_map_usage(hidinput: hi, usage, bit, max, | 
|---|
| 472 | EV_ABS, ABS_MT_POSITION_X); | 
|---|
| 473 | input_set_abs_params(dev: hi->input, ABS_X, | 
|---|
| 474 | min: field->logical_minimum, | 
|---|
| 475 | max: field->logical_maximum, fuzz: 0, flat: 0); | 
|---|
| 476 |  | 
|---|
| 477 | if (!nd->sensor_logical_width) { | 
|---|
| 478 | nd->sensor_logical_width = | 
|---|
| 479 | field->logical_maximum - | 
|---|
| 480 | field->logical_minimum; | 
|---|
| 481 | nd->sensor_physical_width = | 
|---|
| 482 | field->physical_maximum - | 
|---|
| 483 | field->physical_minimum; | 
|---|
| 484 | nd->activation_width = activation_width * | 
|---|
| 485 | nd->sensor_logical_width / | 
|---|
| 486 | nd->sensor_physical_width; | 
|---|
| 487 | nd->min_width = min_width * | 
|---|
| 488 | nd->sensor_logical_width / | 
|---|
| 489 | nd->sensor_physical_width; | 
|---|
| 490 | } | 
|---|
| 491 | return 1; | 
|---|
| 492 | case HID_GD_Y: | 
|---|
| 493 | hid_map_usage(hidinput: hi, usage, bit, max, | 
|---|
| 494 | EV_ABS, ABS_MT_POSITION_Y); | 
|---|
| 495 | input_set_abs_params(dev: hi->input, ABS_Y, | 
|---|
| 496 | min: field->logical_minimum, | 
|---|
| 497 | max: field->logical_maximum, fuzz: 0, flat: 0); | 
|---|
| 498 |  | 
|---|
| 499 | if (!nd->sensor_logical_height) { | 
|---|
| 500 | nd->sensor_logical_height = | 
|---|
| 501 | field->logical_maximum - | 
|---|
| 502 | field->logical_minimum; | 
|---|
| 503 | nd->sensor_physical_height = | 
|---|
| 504 | field->physical_maximum - | 
|---|
| 505 | field->physical_minimum; | 
|---|
| 506 | nd->activation_height = activation_height * | 
|---|
| 507 | nd->sensor_logical_height / | 
|---|
| 508 | nd->sensor_physical_height; | 
|---|
| 509 | nd->min_height = min_height * | 
|---|
| 510 | nd->sensor_logical_height / | 
|---|
| 511 | nd->sensor_physical_height; | 
|---|
| 512 | } | 
|---|
| 513 | return 1; | 
|---|
| 514 | } | 
|---|
| 515 | return 0; | 
|---|
| 516 |  | 
|---|
| 517 | case HID_UP_DIGITIZER: | 
|---|
| 518 | switch (usage->hid) { | 
|---|
| 519 | /* we do not want to map these for now */ | 
|---|
| 520 | case HID_DG_CONTACTID: /* Not trustworthy, squelch for now */ | 
|---|
| 521 | case HID_DG_INPUTMODE: | 
|---|
| 522 | case HID_DG_DEVICEINDEX: | 
|---|
| 523 | case HID_DG_CONTACTMAX: | 
|---|
| 524 | return -1; | 
|---|
| 525 |  | 
|---|
| 526 | /* width/height mapped on TouchMajor/TouchMinor/Orientation */ | 
|---|
| 527 | case HID_DG_WIDTH: | 
|---|
| 528 | hid_map_usage(hidinput: hi, usage, bit, max, | 
|---|
| 529 | EV_ABS, ABS_MT_TOUCH_MAJOR); | 
|---|
| 530 | return 1; | 
|---|
| 531 | case HID_DG_HEIGHT: | 
|---|
| 532 | hid_map_usage(hidinput: hi, usage, bit, max, | 
|---|
| 533 | EV_ABS, ABS_MT_TOUCH_MINOR); | 
|---|
| 534 | input_set_abs_params(dev: hi->input, ABS_MT_ORIENTATION, | 
|---|
| 535 | min: 0, max: 1, fuzz: 0, flat: 0); | 
|---|
| 536 | return 1; | 
|---|
| 537 | } | 
|---|
| 538 | return 0; | 
|---|
| 539 |  | 
|---|
| 540 | case 0xff000000: | 
|---|
| 541 | /* we do not want to map these: no input-oriented meaning */ | 
|---|
| 542 | return -1; | 
|---|
| 543 | } | 
|---|
| 544 |  | 
|---|
| 545 | return 0; | 
|---|
| 546 | } | 
|---|
| 547 |  | 
|---|
| 548 | static int ntrig_input_mapped(struct hid_device *hdev, struct hid_input *hi, | 
|---|
| 549 | struct hid_field *field, struct hid_usage *usage, | 
|---|
| 550 | unsigned long **bit, int *max) | 
|---|
| 551 | { | 
|---|
| 552 | /* No special mappings needed for the pen and single touch */ | 
|---|
| 553 | if (field->physical) | 
|---|
| 554 | return 0; | 
|---|
| 555 |  | 
|---|
| 556 | if (usage->type == EV_KEY || usage->type == EV_REL | 
|---|
| 557 | || usage->type == EV_ABS) | 
|---|
| 558 | clear_bit(nr: usage->code, addr: *bit); | 
|---|
| 559 |  | 
|---|
| 560 | return 0; | 
|---|
| 561 | } | 
|---|
| 562 |  | 
|---|
| 563 | /* | 
|---|
| 564 | * this function is called upon all reports | 
|---|
| 565 | * so that we can filter contact point information, | 
|---|
| 566 | * decide whether we are in multi or single touch mode | 
|---|
| 567 | * and call input_mt_sync after each point if necessary | 
|---|
| 568 | */ | 
|---|
| 569 | static int ntrig_event (struct hid_device *hid, struct hid_field *field, | 
|---|
| 570 | struct hid_usage *usage, __s32 value) | 
|---|
| 571 | { | 
|---|
| 572 | struct ntrig_data *nd = hid_get_drvdata(hdev: hid); | 
|---|
| 573 | struct input_dev *input; | 
|---|
| 574 |  | 
|---|
| 575 | /* Skip processing if not a claimed input */ | 
|---|
| 576 | if (!(hid->claimed & HID_CLAIMED_INPUT)) | 
|---|
| 577 | goto not_claimed_input; | 
|---|
| 578 |  | 
|---|
| 579 | /* This function is being called before the structures are fully | 
|---|
| 580 | * initialized */ | 
|---|
| 581 | if(!(field->hidinput && field->hidinput->input)) | 
|---|
| 582 | return -EINVAL; | 
|---|
| 583 |  | 
|---|
| 584 | input = field->hidinput->input; | 
|---|
| 585 |  | 
|---|
| 586 | /* No special handling needed for the pen */ | 
|---|
| 587 | if (field->application == HID_DG_PEN) | 
|---|
| 588 | return 0; | 
|---|
| 589 |  | 
|---|
| 590 | switch (usage->hid) { | 
|---|
| 591 | case 0xff000001: | 
|---|
| 592 | /* Tag indicating the start of a multitouch group */ | 
|---|
| 593 | nd->reading_mt = true; | 
|---|
| 594 | nd->first_contact_touch = false; | 
|---|
| 595 | break; | 
|---|
| 596 | case HID_DG_TIPSWITCH: | 
|---|
| 597 | nd->tipswitch = value; | 
|---|
| 598 | /* Prevent emission of touch until validated */ | 
|---|
| 599 | return 1; | 
|---|
| 600 | case HID_DG_CONFIDENCE: | 
|---|
| 601 | nd->confidence = value; | 
|---|
| 602 | break; | 
|---|
| 603 | case HID_GD_X: | 
|---|
| 604 | nd->x = value; | 
|---|
| 605 | /* Clear the contact footer */ | 
|---|
| 606 | nd->mt_foot_count = 0; | 
|---|
| 607 | break; | 
|---|
| 608 | case HID_GD_Y: | 
|---|
| 609 | nd->y = value; | 
|---|
| 610 | break; | 
|---|
| 611 | case HID_DG_CONTACTID: | 
|---|
| 612 | nd->id = value; | 
|---|
| 613 | break; | 
|---|
| 614 | case HID_DG_WIDTH: | 
|---|
| 615 | nd->w = value; | 
|---|
| 616 | break; | 
|---|
| 617 | case HID_DG_HEIGHT: | 
|---|
| 618 | nd->h = value; | 
|---|
| 619 | /* | 
|---|
| 620 | * when in single touch mode, this is the last | 
|---|
| 621 | * report received in a finger event. We want | 
|---|
| 622 | * to emit a normal (X, Y) position | 
|---|
| 623 | */ | 
|---|
| 624 | if (!nd->reading_mt) { | 
|---|
| 625 | /* | 
|---|
| 626 | * TipSwitch indicates the presence of a | 
|---|
| 627 | * finger in single touch mode. | 
|---|
| 628 | */ | 
|---|
| 629 | input_report_key(dev: input, BTN_TOUCH, | 
|---|
| 630 | value: nd->tipswitch); | 
|---|
| 631 | input_report_key(dev: input, BTN_TOOL_DOUBLETAP, | 
|---|
| 632 | value: nd->tipswitch); | 
|---|
| 633 | input_event(dev: input, EV_ABS, ABS_X, value: nd->x); | 
|---|
| 634 | input_event(dev: input, EV_ABS, ABS_Y, value: nd->y); | 
|---|
| 635 | } | 
|---|
| 636 | break; | 
|---|
| 637 | case 0xff000002: | 
|---|
| 638 | /* | 
|---|
| 639 | * we receive this when the device is in multitouch | 
|---|
| 640 | * mode. The first of the three values tagged with | 
|---|
| 641 | * this usage tells if the contact point is real | 
|---|
| 642 | * or a placeholder | 
|---|
| 643 | */ | 
|---|
| 644 |  | 
|---|
| 645 | /* Shouldn't get more than 4 footer packets, so skip */ | 
|---|
| 646 | if (nd->mt_foot_count >= 4) | 
|---|
| 647 | break; | 
|---|
| 648 |  | 
|---|
| 649 | nd->mt_footer[nd->mt_foot_count++] = value; | 
|---|
| 650 |  | 
|---|
| 651 | /* if the footer isn't complete break */ | 
|---|
| 652 | if (nd->mt_foot_count != 4) | 
|---|
| 653 | break; | 
|---|
| 654 |  | 
|---|
| 655 | /* Pen activity signal. */ | 
|---|
| 656 | if (nd->mt_footer[2]) { | 
|---|
| 657 | /* | 
|---|
| 658 | * When the pen deactivates touch, we see a | 
|---|
| 659 | * bogus frame with ContactCount > 0. | 
|---|
| 660 | * We can | 
|---|
| 661 | * save a bit of work by ensuring act_state < 0 | 
|---|
| 662 | * even if deactivation slack is turned off. | 
|---|
| 663 | */ | 
|---|
| 664 | nd->act_state = deactivate_slack - 1; | 
|---|
| 665 | nd->confidence = false; | 
|---|
| 666 | break; | 
|---|
| 667 | } | 
|---|
| 668 |  | 
|---|
| 669 | /* | 
|---|
| 670 | * The first footer value indicates the presence of a | 
|---|
| 671 | * finger. | 
|---|
| 672 | */ | 
|---|
| 673 | if (nd->mt_footer[0]) { | 
|---|
| 674 | /* | 
|---|
| 675 | * We do not want to process contacts under | 
|---|
| 676 | * the size threshold, but do not want to | 
|---|
| 677 | * ignore them for activation state | 
|---|
| 678 | */ | 
|---|
| 679 | if (nd->w < nd->min_width || | 
|---|
| 680 | nd->h < nd->min_height) | 
|---|
| 681 | nd->confidence = false; | 
|---|
| 682 | } else | 
|---|
| 683 | break; | 
|---|
| 684 |  | 
|---|
| 685 | if (nd->act_state > 0) { | 
|---|
| 686 | /* | 
|---|
| 687 | * Contact meets the activation size threshold | 
|---|
| 688 | */ | 
|---|
| 689 | if (nd->w >= nd->activation_width && | 
|---|
| 690 | nd->h >= nd->activation_height) { | 
|---|
| 691 | if (nd->id) | 
|---|
| 692 | /* | 
|---|
| 693 | * first contact, activate now | 
|---|
| 694 | */ | 
|---|
| 695 | nd->act_state = 0; | 
|---|
| 696 | else { | 
|---|
| 697 | /* | 
|---|
| 698 | * avoid corrupting this frame | 
|---|
| 699 | * but ensure next frame will | 
|---|
| 700 | * be active | 
|---|
| 701 | */ | 
|---|
| 702 | nd->act_state = 1; | 
|---|
| 703 | break; | 
|---|
| 704 | } | 
|---|
| 705 | } else | 
|---|
| 706 | /* | 
|---|
| 707 | * Defer adjusting the activation state | 
|---|
| 708 | * until the end of the frame. | 
|---|
| 709 | */ | 
|---|
| 710 | break; | 
|---|
| 711 | } | 
|---|
| 712 |  | 
|---|
| 713 | /* Discarding this contact */ | 
|---|
| 714 | if (!nd->confidence) | 
|---|
| 715 | break; | 
|---|
| 716 |  | 
|---|
| 717 | /* emit a normal (X, Y) for the first point only */ | 
|---|
| 718 | if (nd->id == 0) { | 
|---|
| 719 | /* | 
|---|
| 720 | * TipSwitch is superfluous in multitouch | 
|---|
| 721 | * mode.  The footer events tell us | 
|---|
| 722 | * if there is a finger on the screen or | 
|---|
| 723 | * not. | 
|---|
| 724 | */ | 
|---|
| 725 | nd->first_contact_touch = nd->confidence; | 
|---|
| 726 | input_event(dev: input, EV_ABS, ABS_X, value: nd->x); | 
|---|
| 727 | input_event(dev: input, EV_ABS, ABS_Y, value: nd->y); | 
|---|
| 728 | } | 
|---|
| 729 |  | 
|---|
| 730 | /* Emit MT events */ | 
|---|
| 731 | input_event(dev: input, EV_ABS, ABS_MT_POSITION_X, value: nd->x); | 
|---|
| 732 | input_event(dev: input, EV_ABS, ABS_MT_POSITION_Y, value: nd->y); | 
|---|
| 733 |  | 
|---|
| 734 | /* | 
|---|
| 735 | * Translate from height and width to size | 
|---|
| 736 | * and orientation. | 
|---|
| 737 | */ | 
|---|
| 738 | if (nd->w > nd->h) { | 
|---|
| 739 | input_event(dev: input, EV_ABS, | 
|---|
| 740 | ABS_MT_ORIENTATION, value: 1); | 
|---|
| 741 | input_event(dev: input, EV_ABS, | 
|---|
| 742 | ABS_MT_TOUCH_MAJOR, value: nd->w); | 
|---|
| 743 | input_event(dev: input, EV_ABS, | 
|---|
| 744 | ABS_MT_TOUCH_MINOR, value: nd->h); | 
|---|
| 745 | } else { | 
|---|
| 746 | input_event(dev: input, EV_ABS, | 
|---|
| 747 | ABS_MT_ORIENTATION, value: 0); | 
|---|
| 748 | input_event(dev: input, EV_ABS, | 
|---|
| 749 | ABS_MT_TOUCH_MAJOR, value: nd->h); | 
|---|
| 750 | input_event(dev: input, EV_ABS, | 
|---|
| 751 | ABS_MT_TOUCH_MINOR, value: nd->w); | 
|---|
| 752 | } | 
|---|
| 753 | input_mt_sync(dev: field->hidinput->input); | 
|---|
| 754 | break; | 
|---|
| 755 |  | 
|---|
| 756 | case HID_DG_CONTACTCOUNT: /* End of a multitouch group */ | 
|---|
| 757 | if (!nd->reading_mt) /* Just to be sure */ | 
|---|
| 758 | break; | 
|---|
| 759 |  | 
|---|
| 760 | nd->reading_mt = false; | 
|---|
| 761 |  | 
|---|
| 762 |  | 
|---|
| 763 | /* | 
|---|
| 764 | * Activation state machine logic: | 
|---|
| 765 | * | 
|---|
| 766 | * Fundamental states: | 
|---|
| 767 | *	state >  0: Inactive | 
|---|
| 768 | *	state <= 0: Active | 
|---|
| 769 | *	state <  -deactivate_slack: | 
|---|
| 770 | *		 Pen termination of touch | 
|---|
| 771 | * | 
|---|
| 772 | * Specific values of interest | 
|---|
| 773 | *	state == activate_slack | 
|---|
| 774 | *		 no valid input since the last reset | 
|---|
| 775 | * | 
|---|
| 776 | *	state == 0 | 
|---|
| 777 | *		 general operational state | 
|---|
| 778 | * | 
|---|
| 779 | *	state == -deactivate_slack | 
|---|
| 780 | *		 read sufficient empty frames to accept | 
|---|
| 781 | *		 the end of input and reset | 
|---|
| 782 | */ | 
|---|
| 783 |  | 
|---|
| 784 | if (nd->act_state > 0) { /* Currently inactive */ | 
|---|
| 785 | if (value) | 
|---|
| 786 | /* | 
|---|
| 787 | * Consider each live contact as | 
|---|
| 788 | * evidence of intentional activity. | 
|---|
| 789 | */ | 
|---|
| 790 | nd->act_state = (nd->act_state > value) | 
|---|
| 791 | ? nd->act_state - value | 
|---|
| 792 | : 0; | 
|---|
| 793 | else | 
|---|
| 794 | /* | 
|---|
| 795 | * Empty frame before we hit the | 
|---|
| 796 | * activity threshold, reset. | 
|---|
| 797 | */ | 
|---|
| 798 | nd->act_state = nd->activate_slack; | 
|---|
| 799 |  | 
|---|
| 800 | /* | 
|---|
| 801 | * Entered this block inactive and no | 
|---|
| 802 | * coordinates sent this frame, so hold off | 
|---|
| 803 | * on button state. | 
|---|
| 804 | */ | 
|---|
| 805 | break; | 
|---|
| 806 | } else { /* Currently active */ | 
|---|
| 807 | if (value && nd->act_state >= | 
|---|
| 808 | nd->deactivate_slack) | 
|---|
| 809 | /* | 
|---|
| 810 | * Live point: clear accumulated | 
|---|
| 811 | * deactivation count. | 
|---|
| 812 | */ | 
|---|
| 813 | nd->act_state = 0; | 
|---|
| 814 | else if (nd->act_state <= nd->deactivate_slack) | 
|---|
| 815 | /* | 
|---|
| 816 | * We've consumed the deactivation | 
|---|
| 817 | * slack, time to deactivate and reset. | 
|---|
| 818 | */ | 
|---|
| 819 | nd->act_state = | 
|---|
| 820 | nd->activate_slack; | 
|---|
| 821 | else { /* Move towards deactivation */ | 
|---|
| 822 | nd->act_state--; | 
|---|
| 823 | break; | 
|---|
| 824 | } | 
|---|
| 825 | } | 
|---|
| 826 |  | 
|---|
| 827 | if (nd->first_contact_touch && nd->act_state <= 0) { | 
|---|
| 828 | /* | 
|---|
| 829 | * Check to see if we're ready to start | 
|---|
| 830 | * emitting touch events. | 
|---|
| 831 | * | 
|---|
| 832 | * Note: activation slack will decrease over | 
|---|
| 833 | * the course of the frame, and it will be | 
|---|
| 834 | * inconsistent from the start to the end of | 
|---|
| 835 | * the frame.  However if the frame starts | 
|---|
| 836 | * with slack, first_contact_touch will still | 
|---|
| 837 | * be 0 and we will not get to this point. | 
|---|
| 838 | */ | 
|---|
| 839 | input_report_key(dev: input, BTN_TOOL_DOUBLETAP, value: 1); | 
|---|
| 840 | input_report_key(dev: input, BTN_TOUCH, value: 1); | 
|---|
| 841 | } else { | 
|---|
| 842 | input_report_key(dev: input, BTN_TOOL_DOUBLETAP, value: 0); | 
|---|
| 843 | input_report_key(dev: input, BTN_TOUCH, value: 0); | 
|---|
| 844 | } | 
|---|
| 845 | break; | 
|---|
| 846 |  | 
|---|
| 847 | default: | 
|---|
| 848 | /* fall-back to the generic hidinput handling */ | 
|---|
| 849 | return 0; | 
|---|
| 850 | } | 
|---|
| 851 |  | 
|---|
| 852 | not_claimed_input: | 
|---|
| 853 |  | 
|---|
| 854 | /* we have handled the hidinput part, now remains hiddev */ | 
|---|
| 855 | if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_hid_event) | 
|---|
| 856 | hid->hiddev_hid_event(hid, field, usage, value); | 
|---|
| 857 |  | 
|---|
| 858 | return 1; | 
|---|
| 859 | } | 
|---|
| 860 |  | 
|---|
| 861 | static int ntrig_input_configured(struct hid_device *hid, | 
|---|
| 862 | struct hid_input *hidinput) | 
|---|
| 863 |  | 
|---|
| 864 | { | 
|---|
| 865 | struct input_dev *input = hidinput->input; | 
|---|
| 866 |  | 
|---|
| 867 | if (hidinput->report->maxfield < 1) | 
|---|
| 868 | return 0; | 
|---|
| 869 |  | 
|---|
| 870 | switch (hidinput->report->field[0]->application) { | 
|---|
| 871 | case HID_DG_PEN: | 
|---|
| 872 | input->name = "N-Trig Pen"; | 
|---|
| 873 | break; | 
|---|
| 874 | case HID_DG_TOUCHSCREEN: | 
|---|
| 875 | /* These keys are redundant for fingers, clear them | 
|---|
| 876 | * to prevent incorrect identification */ | 
|---|
| 877 | __clear_bit(BTN_TOOL_PEN, input->keybit); | 
|---|
| 878 | __clear_bit(BTN_TOOL_FINGER, input->keybit); | 
|---|
| 879 | __clear_bit(BTN_0, input->keybit); | 
|---|
| 880 | __set_bit(BTN_TOOL_DOUBLETAP, input->keybit); | 
|---|
| 881 | /* | 
|---|
| 882 | * The physical touchscreen (single touch) | 
|---|
| 883 | * input has a value for physical, whereas | 
|---|
| 884 | * the multitouch only has logical input | 
|---|
| 885 | * fields. | 
|---|
| 886 | */ | 
|---|
| 887 | input->name = (hidinput->report->field[0]->physical) ? | 
|---|
| 888 | "N-Trig Touchscreen": | 
|---|
| 889 | "N-Trig MultiTouch"; | 
|---|
| 890 | break; | 
|---|
| 891 | } | 
|---|
| 892 |  | 
|---|
| 893 | return 0; | 
|---|
| 894 | } | 
|---|
| 895 |  | 
|---|
| 896 | static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) | 
|---|
| 897 | { | 
|---|
| 898 | int ret; | 
|---|
| 899 | struct ntrig_data *nd; | 
|---|
| 900 | struct hid_report *report; | 
|---|
| 901 |  | 
|---|
| 902 | if (id->driver_data) | 
|---|
| 903 | hdev->quirks |= HID_QUIRK_MULTI_INPUT | 
|---|
| 904 | | HID_QUIRK_NO_INIT_REPORTS; | 
|---|
| 905 |  | 
|---|
| 906 | nd = kmalloc(sizeof(struct ntrig_data), GFP_KERNEL); | 
|---|
| 907 | if (!nd) { | 
|---|
| 908 | hid_err(hdev, "cannot allocate N-Trig data\n"); | 
|---|
| 909 | return -ENOMEM; | 
|---|
| 910 | } | 
|---|
| 911 |  | 
|---|
| 912 | nd->reading_mt = false; | 
|---|
| 913 | nd->min_width = 0; | 
|---|
| 914 | nd->min_height = 0; | 
|---|
| 915 | nd->activate_slack = activate_slack; | 
|---|
| 916 | nd->act_state = activate_slack; | 
|---|
| 917 | nd->deactivate_slack = -deactivate_slack; | 
|---|
| 918 | nd->sensor_logical_width = 1; | 
|---|
| 919 | nd->sensor_logical_height = 1; | 
|---|
| 920 | nd->sensor_physical_width = 1; | 
|---|
| 921 | nd->sensor_physical_height = 1; | 
|---|
| 922 |  | 
|---|
| 923 | hid_set_drvdata(hdev, data: nd); | 
|---|
| 924 |  | 
|---|
| 925 | ret = hid_parse(hdev); | 
|---|
| 926 | if (ret) { | 
|---|
| 927 | hid_err(hdev, "parse failed\n"); | 
|---|
| 928 | goto err_free; | 
|---|
| 929 | } | 
|---|
| 930 |  | 
|---|
| 931 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); | 
|---|
| 932 | if (ret) { | 
|---|
| 933 | hid_err(hdev, "hw start failed\n"); | 
|---|
| 934 | goto err_free; | 
|---|
| 935 | } | 
|---|
| 936 |  | 
|---|
| 937 | /* This is needed for devices with more recent firmware versions */ | 
|---|
| 938 | report = hdev->report_enum[HID_FEATURE_REPORT].report_id_hash[0x0a]; | 
|---|
| 939 | if (report) { | 
|---|
| 940 | /* Let the device settle to ensure the wakeup message gets | 
|---|
| 941 | * through */ | 
|---|
| 942 | hid_hw_wait(hdev); | 
|---|
| 943 | hid_hw_request(hdev, report, reqtype: HID_REQ_GET_REPORT); | 
|---|
| 944 |  | 
|---|
| 945 | /* | 
|---|
| 946 | * Sanity check: if the current mode is invalid reset it to | 
|---|
| 947 | * something reasonable. | 
|---|
| 948 | */ | 
|---|
| 949 | if (ntrig_get_mode(hdev) >= 4) | 
|---|
| 950 | ntrig_set_mode(hdev, mode: 3); | 
|---|
| 951 | } | 
|---|
| 952 |  | 
|---|
| 953 | ntrig_report_version(hdev); | 
|---|
| 954 |  | 
|---|
| 955 | ret = sysfs_create_group(kobj: &hdev->dev.kobj, | 
|---|
| 956 | grp: &ntrig_attribute_group); | 
|---|
| 957 | if (ret) | 
|---|
| 958 | hid_err(hdev, "cannot create sysfs group\n"); | 
|---|
| 959 |  | 
|---|
| 960 | return 0; | 
|---|
| 961 | err_free: | 
|---|
| 962 | kfree(objp: nd); | 
|---|
| 963 | return ret; | 
|---|
| 964 | } | 
|---|
| 965 |  | 
|---|
| 966 | static void ntrig_remove(struct hid_device *hdev) | 
|---|
| 967 | { | 
|---|
| 968 | sysfs_remove_group(kobj: &hdev->dev.kobj, | 
|---|
| 969 | grp: &ntrig_attribute_group); | 
|---|
| 970 | hid_hw_stop(hdev); | 
|---|
| 971 | kfree(objp: hid_get_drvdata(hdev)); | 
|---|
| 972 | } | 
|---|
| 973 |  | 
|---|
| 974 | static const struct hid_device_id ntrig_devices[] = { | 
|---|
| 975 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN), | 
|---|
| 976 | .driver_data = NTRIG_DUPLICATE_USAGES }, | 
|---|
| 977 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1), | 
|---|
| 978 | .driver_data = NTRIG_DUPLICATE_USAGES }, | 
|---|
| 979 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_2), | 
|---|
| 980 | .driver_data = NTRIG_DUPLICATE_USAGES }, | 
|---|
| 981 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_3), | 
|---|
| 982 | .driver_data = NTRIG_DUPLICATE_USAGES }, | 
|---|
| 983 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_4), | 
|---|
| 984 | .driver_data = NTRIG_DUPLICATE_USAGES }, | 
|---|
| 985 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_5), | 
|---|
| 986 | .driver_data = NTRIG_DUPLICATE_USAGES }, | 
|---|
| 987 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_6), | 
|---|
| 988 | .driver_data = NTRIG_DUPLICATE_USAGES }, | 
|---|
| 989 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_7), | 
|---|
| 990 | .driver_data = NTRIG_DUPLICATE_USAGES }, | 
|---|
| 991 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_8), | 
|---|
| 992 | .driver_data = NTRIG_DUPLICATE_USAGES }, | 
|---|
| 993 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_9), | 
|---|
| 994 | .driver_data = NTRIG_DUPLICATE_USAGES }, | 
|---|
| 995 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_10), | 
|---|
| 996 | .driver_data = NTRIG_DUPLICATE_USAGES }, | 
|---|
| 997 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_11), | 
|---|
| 998 | .driver_data = NTRIG_DUPLICATE_USAGES }, | 
|---|
| 999 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_12), | 
|---|
| 1000 | .driver_data = NTRIG_DUPLICATE_USAGES }, | 
|---|
| 1001 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_13), | 
|---|
| 1002 | .driver_data = NTRIG_DUPLICATE_USAGES }, | 
|---|
| 1003 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_14), | 
|---|
| 1004 | .driver_data = NTRIG_DUPLICATE_USAGES }, | 
|---|
| 1005 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_15), | 
|---|
| 1006 | .driver_data = NTRIG_DUPLICATE_USAGES }, | 
|---|
| 1007 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_16), | 
|---|
| 1008 | .driver_data = NTRIG_DUPLICATE_USAGES }, | 
|---|
| 1009 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_17), | 
|---|
| 1010 | .driver_data = NTRIG_DUPLICATE_USAGES }, | 
|---|
| 1011 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_18), | 
|---|
| 1012 | .driver_data = NTRIG_DUPLICATE_USAGES }, | 
|---|
| 1013 | { } | 
|---|
| 1014 | }; | 
|---|
| 1015 | MODULE_DEVICE_TABLE(hid, ntrig_devices); | 
|---|
| 1016 |  | 
|---|
| 1017 | static const struct hid_usage_id ntrig_grabbed_usages[] = { | 
|---|
| 1018 | { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID }, | 
|---|
| 1019 | { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1 } | 
|---|
| 1020 | }; | 
|---|
| 1021 |  | 
|---|
| 1022 | static struct hid_driver ntrig_driver = { | 
|---|
| 1023 | .name = "ntrig", | 
|---|
| 1024 | .id_table = ntrig_devices, | 
|---|
| 1025 | .probe = ntrig_probe, | 
|---|
| 1026 | .remove = ntrig_remove, | 
|---|
| 1027 | .input_mapping = ntrig_input_mapping, | 
|---|
| 1028 | .input_mapped = ntrig_input_mapped, | 
|---|
| 1029 | .input_configured = ntrig_input_configured, | 
|---|
| 1030 | .usage_table = ntrig_grabbed_usages, | 
|---|
| 1031 | .event = ntrig_event, | 
|---|
| 1032 | }; | 
|---|
| 1033 | module_hid_driver(ntrig_driver); | 
|---|
| 1034 |  | 
|---|
| 1035 | MODULE_DESCRIPTION( "HID driver for N-Trig touchscreens"); | 
|---|
| 1036 | MODULE_LICENSE( "GPL"); | 
|---|
| 1037 |  | 
|---|