Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  *  HID driver for ViewSonic devices not fully compliant with HID standard
0004  *
0005  *  Copyright (c) 2017 Nikolai Kondrashov
0006  */
0007 
0008 /*
0009  * This program is free software; you can redistribute it and/or modify it
0010  * under the terms of the GNU General Public License as published by the Free
0011  * Software Foundation; either version 2 of the License, or (at your option)
0012  * any later version.
0013  */
0014 
0015 #include <linux/device.h>
0016 #include <linux/hid.h>
0017 #include <linux/module.h>
0018 
0019 #include "hid-ids.h"
0020 
0021 /* Size of the original descriptor of PD1011 signature pad */
0022 #define PD1011_RDESC_ORIG_SIZE  408
0023 
0024 /* Fixed report descriptor of PD1011 signature pad */
0025 static __u8 pd1011_rdesc_fixed[] = {
0026     0x05, 0x0D,             /*  Usage Page (Digitizer),             */
0027     0x09, 0x01,             /*  Usage (Digitizer),                  */
0028     0xA1, 0x01,             /*  Collection (Application),           */
0029     0x85, 0x02,             /*      Report ID (2),                  */
0030     0x09, 0x20,             /*      Usage (Stylus),                 */
0031     0xA0,                   /*      Collection (Physical),          */
0032     0x75, 0x10,             /*          Report Size (16),           */
0033     0x95, 0x01,             /*          Report Count (1),           */
0034     0xA4,                   /*          Push,                       */
0035     0x05, 0x01,             /*          Usage Page (Desktop),       */
0036     0x65, 0x13,             /*          Unit (Inch),                */
0037     0x55, 0xFD,             /*          Unit Exponent (-3),         */
0038     0x34,                   /*          Physical Minimum (0),       */
0039     0x09, 0x30,             /*          Usage (X),                  */
0040     0x46, 0x5D, 0x21,       /*          Physical Maximum (8541),    */
0041     0x27, 0x80, 0xA9,
0042         0x00, 0x00,     /*          Logical Maximum (43392),    */
0043     0x81, 0x02,             /*          Input (Variable),           */
0044     0x09, 0x31,             /*          Usage (Y),                  */
0045     0x46, 0xDA, 0x14,       /*          Physical Maximum (5338),    */
0046     0x26, 0xF0, 0x69,       /*          Logical Maximum (27120),    */
0047     0x81, 0x02,             /*          Input (Variable),           */
0048     0xB4,                   /*          Pop,                        */
0049     0x14,                   /*          Logical Minimum (0),        */
0050     0x25, 0x01,             /*          Logical Maximum (1),        */
0051     0x75, 0x01,             /*          Report Size (1),            */
0052     0x95, 0x01,             /*          Report Count (1),           */
0053     0x81, 0x03,             /*          Input (Constant, Variable), */
0054     0x09, 0x32,             /*          Usage (In Range),           */
0055     0x09, 0x42,             /*          Usage (Tip Switch),         */
0056     0x95, 0x02,             /*          Report Count (2),           */
0057     0x81, 0x02,             /*          Input (Variable),           */
0058     0x95, 0x05,             /*          Report Count (5),           */
0059     0x81, 0x03,             /*          Input (Constant, Variable), */
0060     0x75, 0x10,             /*          Report Size (16),           */
0061     0x95, 0x01,             /*          Report Count (1),           */
0062     0x09, 0x30,             /*          Usage (Tip Pressure),       */
0063     0x15, 0x05,             /*          Logical Minimum (5),        */
0064     0x26, 0xFF, 0x07,       /*          Logical Maximum (2047),     */
0065     0x81, 0x02,             /*          Input (Variable),           */
0066     0x75, 0x10,             /*          Report Size (16),           */
0067     0x95, 0x01,             /*          Report Count (1),           */
0068     0x81, 0x03,             /*          Input (Constant, Variable), */
0069     0xC0,                   /*      End Collection,                 */
0070     0xC0                    /*  End Collection                      */
0071 };
0072 
0073 static __u8 *viewsonic_report_fixup(struct hid_device *hdev, __u8 *rdesc,
0074                     unsigned int *rsize)
0075 {
0076     switch (hdev->product) {
0077     case USB_DEVICE_ID_VIEWSONIC_PD1011:
0078     case USB_DEVICE_ID_SIGNOTEC_VIEWSONIC_PD1011:
0079         if (*rsize == PD1011_RDESC_ORIG_SIZE) {
0080             rdesc = pd1011_rdesc_fixed;
0081             *rsize = sizeof(pd1011_rdesc_fixed);
0082         }
0083         break;
0084     }
0085 
0086     return rdesc;
0087 }
0088 
0089 static const struct hid_device_id viewsonic_devices[] = {
0090     { HID_USB_DEVICE(USB_VENDOR_ID_VIEWSONIC,
0091                 USB_DEVICE_ID_VIEWSONIC_PD1011) },
0092     { HID_USB_DEVICE(USB_VENDOR_ID_SIGNOTEC,
0093                 USB_DEVICE_ID_SIGNOTEC_VIEWSONIC_PD1011) },
0094     { }
0095 };
0096 MODULE_DEVICE_TABLE(hid, viewsonic_devices);
0097 
0098 static struct hid_driver viewsonic_driver = {
0099     .name = "viewsonic",
0100     .id_table = viewsonic_devices,
0101     .report_fixup = viewsonic_report_fixup,
0102 };
0103 module_hid_driver(viewsonic_driver);
0104 
0105 MODULE_LICENSE("GPL");