Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * HID driver for ELO usb touchscreen 4000/4500
0004  *
0005  * Copyright (c) 2013 Jiri Slaby
0006  *
0007  * Data parsing taken from elousb driver by Vojtech Pavlik.
0008  */
0009 
0010 #include <linux/hid.h>
0011 #include <linux/input.h>
0012 #include <linux/module.h>
0013 #include <linux/usb.h>
0014 #include <linux/workqueue.h>
0015 
0016 #include "hid-ids.h"
0017 
0018 #define ELO_PERIODIC_READ_INTERVAL  HZ
0019 #define ELO_SMARTSET_CMD_TIMEOUT    2000 /* msec */
0020 
0021 /* Elo SmartSet commands */
0022 #define ELO_FLUSH_SMARTSET_RESPONSES    0x02 /* Flush all pending smartset responses */
0023 #define ELO_SEND_SMARTSET_COMMAND   0x05 /* Send a smartset command */
0024 #define ELO_GET_SMARTSET_RESPONSE   0x06 /* Get a smartset response */
0025 #define ELO_DIAG            0x64 /* Diagnostics command */
0026 #define ELO_SMARTSET_PACKET_SIZE    8
0027 
0028 struct elo_priv {
0029     struct usb_device *usbdev;
0030     struct delayed_work work;
0031     unsigned char buffer[ELO_SMARTSET_PACKET_SIZE];
0032 };
0033 
0034 static struct workqueue_struct *wq;
0035 static bool use_fw_quirk = true;
0036 module_param(use_fw_quirk, bool, S_IRUGO);
0037 MODULE_PARM_DESC(use_fw_quirk, "Do periodic pokes for broken M firmwares (default = true)");
0038 
0039 static int elo_input_configured(struct hid_device *hdev,
0040         struct hid_input *hidinput)
0041 {
0042     struct input_dev *input = hidinput->input;
0043 
0044     /*
0045      * ELO devices have one Button usage in GenDesk field, which makes
0046      * hid-input map it to BTN_LEFT; that confuses userspace, which then
0047      * considers the device to be a mouse/touchpad instead of touchscreen.
0048      */
0049     clear_bit(BTN_LEFT, input->keybit);
0050     set_bit(BTN_TOUCH, input->keybit);
0051     set_bit(ABS_PRESSURE, input->absbit);
0052     input_set_abs_params(input, ABS_PRESSURE, 0, 256, 0, 0);
0053 
0054     return 0;
0055 }
0056 
0057 static void elo_process_data(struct input_dev *input, const u8 *data, int size)
0058 {
0059     int press;
0060 
0061     input_report_abs(input, ABS_X, (data[3] << 8) | data[2]);
0062     input_report_abs(input, ABS_Y, (data[5] << 8) | data[4]);
0063 
0064     press = 0;
0065     if (data[1] & 0x80)
0066         press = (data[7] << 8) | data[6];
0067     input_report_abs(input, ABS_PRESSURE, press);
0068 
0069     if (data[1] & 0x03) {
0070         input_report_key(input, BTN_TOUCH, 1);
0071         input_sync(input);
0072     }
0073 
0074     if (data[1] & 0x04)
0075         input_report_key(input, BTN_TOUCH, 0);
0076 
0077     input_sync(input);
0078 }
0079 
0080 static int elo_raw_event(struct hid_device *hdev, struct hid_report *report,
0081      u8 *data, int size)
0082 {
0083     struct hid_input *hidinput;
0084 
0085     if (!(hdev->claimed & HID_CLAIMED_INPUT) || list_empty(&hdev->inputs))
0086         return 0;
0087 
0088     hidinput = list_first_entry(&hdev->inputs, struct hid_input, list);
0089 
0090     switch (report->id) {
0091     case 0:
0092         if (data[0] == 'T') {   /* Mandatory ELO packet marker */
0093             elo_process_data(hidinput->input, data, size);
0094             return 1;
0095         }
0096         break;
0097     default:    /* unknown report */
0098         /* Unknown report type; pass upstream */
0099         hid_info(hdev, "unknown report type %d\n", report->id);
0100         break;
0101     }
0102 
0103     return 0;
0104 }
0105 
0106 static int elo_smartset_send_get(struct usb_device *dev, u8 command,
0107         void *data)
0108 {
0109     unsigned int pipe;
0110     u8 dir;
0111 
0112     if (command == ELO_SEND_SMARTSET_COMMAND) {
0113         pipe = usb_sndctrlpipe(dev, 0);
0114         dir = USB_DIR_OUT;
0115     } else if (command == ELO_GET_SMARTSET_RESPONSE) {
0116         pipe = usb_rcvctrlpipe(dev, 0);
0117         dir = USB_DIR_IN;
0118     } else
0119         return -EINVAL;
0120 
0121     return usb_control_msg(dev, pipe, command,
0122             dir | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0123             0, 0, data, ELO_SMARTSET_PACKET_SIZE,
0124             ELO_SMARTSET_CMD_TIMEOUT);
0125 }
0126 
0127 static int elo_flush_smartset_responses(struct usb_device *dev)
0128 {
0129     return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
0130             ELO_FLUSH_SMARTSET_RESPONSES,
0131             USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0132             0, 0, NULL, 0, USB_CTRL_SET_TIMEOUT);
0133 }
0134 
0135 static void elo_work(struct work_struct *work)
0136 {
0137     struct elo_priv *priv = container_of(work, struct elo_priv, work.work);
0138     struct usb_device *dev = priv->usbdev;
0139     unsigned char *buffer = priv->buffer;
0140     int ret;
0141 
0142     ret = elo_flush_smartset_responses(dev);
0143     if (ret < 0) {
0144         dev_err(&dev->dev, "initial FLUSH_SMARTSET_RESPONSES failed, error %d\n",
0145                 ret);
0146         goto fail;
0147     }
0148 
0149     /* send Diagnostics command */
0150     *buffer = ELO_DIAG;
0151     ret = elo_smartset_send_get(dev, ELO_SEND_SMARTSET_COMMAND, buffer);
0152     if (ret < 0) {
0153         dev_err(&dev->dev, "send Diagnostics Command failed, error %d\n",
0154                 ret);
0155         goto fail;
0156     }
0157 
0158     /* get the result */
0159     ret = elo_smartset_send_get(dev, ELO_GET_SMARTSET_RESPONSE, buffer);
0160     if (ret < 0) {
0161         dev_err(&dev->dev, "get Diagnostics Command response failed, error %d\n",
0162                 ret);
0163         goto fail;
0164     }
0165 
0166     /* read the ack */
0167     if (*buffer != 'A') {
0168         ret = elo_smartset_send_get(dev, ELO_GET_SMARTSET_RESPONSE,
0169                 buffer);
0170         if (ret < 0) {
0171             dev_err(&dev->dev, "get acknowledge response failed, error %d\n",
0172                     ret);
0173             goto fail;
0174         }
0175     }
0176 
0177 fail:
0178     ret = elo_flush_smartset_responses(dev);
0179     if (ret < 0)
0180         dev_err(&dev->dev, "final FLUSH_SMARTSET_RESPONSES failed, error %d\n",
0181                 ret);
0182     queue_delayed_work(wq, &priv->work, ELO_PERIODIC_READ_INTERVAL);
0183 }
0184 
0185 /*
0186  * Not all Elo devices need the periodic HID descriptor reads.
0187  * Only firmware version M needs this.
0188  */
0189 static bool elo_broken_firmware(struct usb_device *dev)
0190 {
0191     struct usb_device *hub = dev->parent;
0192     struct usb_device *child = NULL;
0193     u16 fw_lvl = le16_to_cpu(dev->descriptor.bcdDevice);
0194     u16 child_vid, child_pid;
0195     int i;
0196     
0197     if (!use_fw_quirk)
0198         return false;
0199     if (fw_lvl != 0x10d)
0200         return false;
0201 
0202     /* iterate sibling devices of the touch controller */
0203     usb_hub_for_each_child(hub, i, child) {
0204         child_vid = le16_to_cpu(child->descriptor.idVendor);
0205         child_pid = le16_to_cpu(child->descriptor.idProduct);
0206 
0207         /*
0208          * If one of the devices below is present attached as a sibling of 
0209          * the touch controller then  this is a newer IBM 4820 monitor that 
0210          * does not need the IBM-requested workaround if fw level is
0211          * 0x010d - aka 'M'.
0212          * No other HW can have this combination.
0213          */
0214         if (child_vid==0x04b3) {
0215             switch (child_pid) {
0216             case 0x4676: /* 4820 21x Video */
0217             case 0x4677: /* 4820 51x Video */
0218             case 0x4678: /* 4820 2Lx Video */
0219             case 0x4679: /* 4820 5Lx Video */
0220                 return false;
0221             }
0222         }
0223     }
0224     return true;
0225 }
0226 
0227 static int elo_probe(struct hid_device *hdev, const struct hid_device_id *id)
0228 {
0229     struct elo_priv *priv;
0230     int ret;
0231 
0232     if (!hid_is_usb(hdev))
0233         return -EINVAL;
0234 
0235     priv = kzalloc(sizeof(*priv), GFP_KERNEL);
0236     if (!priv)
0237         return -ENOMEM;
0238 
0239     INIT_DELAYED_WORK(&priv->work, elo_work);
0240     priv->usbdev = interface_to_usbdev(to_usb_interface(hdev->dev.parent));
0241 
0242     hid_set_drvdata(hdev, priv);
0243 
0244     ret = hid_parse(hdev);
0245     if (ret) {
0246         hid_err(hdev, "parse failed\n");
0247         goto err_free;
0248     }
0249 
0250     ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
0251     if (ret) {
0252         hid_err(hdev, "hw start failed\n");
0253         goto err_free;
0254     }
0255 
0256     if (elo_broken_firmware(priv->usbdev)) {
0257         hid_info(hdev, "broken firmware found, installing workaround\n");
0258         queue_delayed_work(wq, &priv->work, ELO_PERIODIC_READ_INTERVAL);
0259     }
0260 
0261     return 0;
0262 err_free:
0263     kfree(priv);
0264     return ret;
0265 }
0266 
0267 static void elo_remove(struct hid_device *hdev)
0268 {
0269     struct elo_priv *priv = hid_get_drvdata(hdev);
0270 
0271     hid_hw_stop(hdev);
0272     cancel_delayed_work_sync(&priv->work);
0273     kfree(priv);
0274 }
0275 
0276 static const struct hid_device_id elo_devices[] = {
0277     { HID_USB_DEVICE(USB_VENDOR_ID_ELO, 0x0009), },
0278     { HID_USB_DEVICE(USB_VENDOR_ID_ELO, 0x0030), },
0279     { }
0280 };
0281 MODULE_DEVICE_TABLE(hid, elo_devices);
0282 
0283 static struct hid_driver elo_driver = {
0284     .name = "elo",
0285     .id_table = elo_devices,
0286     .probe = elo_probe,
0287     .remove = elo_remove,
0288     .raw_event = elo_raw_event,
0289     .input_configured = elo_input_configured,
0290 };
0291 
0292 static int __init elo_driver_init(void)
0293 {
0294     int ret;
0295 
0296     wq = create_singlethread_workqueue("elousb");
0297     if (!wq)
0298         return -ENOMEM;
0299 
0300     ret = hid_register_driver(&elo_driver);
0301     if (ret)
0302         destroy_workqueue(wq);
0303 
0304     return ret;
0305 }
0306 module_init(elo_driver_init);
0307 
0308 static void __exit elo_driver_exit(void)
0309 {
0310     hid_unregister_driver(&elo_driver);
0311     destroy_workqueue(wq);
0312 }
0313 module_exit(elo_driver_exit);
0314 
0315 MODULE_AUTHOR("Jiri Slaby <jslaby@suse.cz>");
0316 MODULE_LICENSE("GPL");