1 /* 2 * HID driver for ELO usb touchscreen 4000/4500 3 * 4 * Copyright (c) 2013 Jiri Slaby 5 * 6 * Data parsing taken from elousb driver by Vojtech Pavlik. 7 * 8 * This driver is licensed under the terms of GPLv2. 9 */ 10 11 #include <linux/hid.h> 12 #include <linux/input.h> 13 #include <linux/module.h> 14 #include <linux/usb.h> 15 #include <linux/workqueue.h> 16 17 #include "hid-ids.h" 18 19 #define ELO_PERIODIC_READ_INTERVAL HZ 20 #define ELO_SMARTSET_CMD_TIMEOUT 2000 /* msec */ 21 22 /* Elo SmartSet commands */ 23 #define ELO_FLUSH_SMARTSET_RESPONSES 0x02 /* Flush all pending smartset responses */ 24 #define ELO_SEND_SMARTSET_COMMAND 0x05 /* Send a smartset command */ 25 #define ELO_GET_SMARTSET_RESPONSE 0x06 /* Get a smartset response */ 26 #define ELO_DIAG 0x64 /* Diagnostics command */ 27 #define ELO_SMARTSET_PACKET_SIZE 8 28 29 struct elo_priv { 30 struct usb_device *usbdev; 31 struct delayed_work work; 32 unsigned char buffer[ELO_SMARTSET_PACKET_SIZE]; 33 }; 34 35 static struct workqueue_struct *wq; 36 static bool use_fw_quirk = true; 37 module_param(use_fw_quirk, bool, S_IRUGO); 38 MODULE_PARM_DESC(use_fw_quirk, "Do periodic pokes for broken M firmwares (default = true)"); 39 40 static void elo_input_configured(struct hid_device *hdev, 41 struct hid_input *hidinput) 42 { 43 struct input_dev *input = hidinput->input; 44 45 set_bit(BTN_TOUCH, input->keybit); 46 set_bit(ABS_PRESSURE, input->absbit); 47 input_set_abs_params(input, ABS_PRESSURE, 0, 256, 0, 0); 48 } 49 50 static void elo_process_data(struct input_dev *input, const u8 *data, int size) 51 { 52 int press; 53 54 input_report_abs(input, ABS_X, (data[3] << 8) | data[2]); 55 input_report_abs(input, ABS_Y, (data[5] << 8) | data[4]); 56 57 press = 0; 58 if (data[1] & 0x80) 59 press = (data[7] << 8) | data[6]; 60 input_report_abs(input, ABS_PRESSURE, press); 61 62 if (data[1] & 0x03) { 63 input_report_key(input, BTN_TOUCH, 1); 64 input_sync(input); 65 } 66 67 if (data[1] & 0x04) 68 input_report_key(input, BTN_TOUCH, 0); 69 70 input_sync(input); 71 } 72 73 static int elo_raw_event(struct hid_device *hdev, struct hid_report *report, 74 u8 *data, int size) 75 { 76 struct hid_input *hidinput; 77 78 if (!(hdev->claimed & HID_CLAIMED_INPUT) || list_empty(&hdev->inputs)) 79 return 0; 80 81 hidinput = list_first_entry(&hdev->inputs, struct hid_input, list); 82 83 switch (report->id) { 84 case 0: 85 if (data[0] == 'T') { /* Mandatory ELO packet marker */ 86 elo_process_data(hidinput->input, data, size); 87 return 1; 88 } 89 break; 90 default: /* unknown report */ 91 /* Unknown report type; pass upstream */ 92 hid_info(hdev, "unknown report type %d\n", report->id); 93 break; 94 } 95 96 return 0; 97 } 98 99 static int elo_smartset_send_get(struct usb_device *dev, u8 command, 100 void *data) 101 { 102 unsigned int pipe; 103 u8 dir; 104 105 if (command == ELO_SEND_SMARTSET_COMMAND) { 106 pipe = usb_sndctrlpipe(dev, 0); 107 dir = USB_DIR_OUT; 108 } else if (command == ELO_GET_SMARTSET_RESPONSE) { 109 pipe = usb_rcvctrlpipe(dev, 0); 110 dir = USB_DIR_IN; 111 } else 112 return -EINVAL; 113 114 return usb_control_msg(dev, pipe, command, 115 dir | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 116 0, 0, data, ELO_SMARTSET_PACKET_SIZE, 117 ELO_SMARTSET_CMD_TIMEOUT); 118 } 119 120 static int elo_flush_smartset_responses(struct usb_device *dev) 121 { 122 return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 123 ELO_FLUSH_SMARTSET_RESPONSES, 124 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 125 0, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); 126 } 127 128 static void elo_work(struct work_struct *work) 129 { 130 struct elo_priv *priv = container_of(work, struct elo_priv, work.work); 131 struct usb_device *dev = priv->usbdev; 132 unsigned char *buffer = priv->buffer; 133 int ret; 134 135 ret = elo_flush_smartset_responses(dev); 136 if (ret < 0) { 137 dev_err(&dev->dev, "initial FLUSH_SMARTSET_RESPONSES failed, error %d\n", 138 ret); 139 goto fail; 140 } 141 142 /* send Diagnostics command */ 143 *buffer = ELO_DIAG; 144 ret = elo_smartset_send_get(dev, ELO_SEND_SMARTSET_COMMAND, buffer); 145 if (ret < 0) { 146 dev_err(&dev->dev, "send Diagnostics Command failed, error %d\n", 147 ret); 148 goto fail; 149 } 150 151 /* get the result */ 152 ret = elo_smartset_send_get(dev, ELO_GET_SMARTSET_RESPONSE, buffer); 153 if (ret < 0) { 154 dev_err(&dev->dev, "get Diagnostics Command response failed, error %d\n", 155 ret); 156 goto fail; 157 } 158 159 /* read the ack */ 160 if (*buffer != 'A') { 161 ret = elo_smartset_send_get(dev, ELO_GET_SMARTSET_RESPONSE, 162 buffer); 163 if (ret < 0) { 164 dev_err(&dev->dev, "get acknowledge response failed, error %d\n", 165 ret); 166 goto fail; 167 } 168 } 169 170 fail: 171 ret = elo_flush_smartset_responses(dev); 172 if (ret < 0) 173 dev_err(&dev->dev, "final FLUSH_SMARTSET_RESPONSES failed, error %d\n", 174 ret); 175 queue_delayed_work(wq, &priv->work, ELO_PERIODIC_READ_INTERVAL); 176 } 177 178 /* 179 * Not all Elo devices need the periodic HID descriptor reads. 180 * Only firmware version M needs this. 181 */ 182 static bool elo_broken_firmware(struct usb_device *dev) 183 { 184 struct usb_device *hub = dev->parent; 185 struct usb_device *child = NULL; 186 u16 fw_lvl = le16_to_cpu(dev->descriptor.bcdDevice); 187 u16 child_vid, child_pid; 188 int i; 189 190 if (!use_fw_quirk) 191 return false; 192 if (fw_lvl != 0x10d) 193 return false; 194 195 /* iterate sibling devices of the touch controller */ 196 usb_hub_for_each_child(hub, i, child) { 197 child_vid = le16_to_cpu(child->descriptor.idVendor); 198 child_pid = le16_to_cpu(child->descriptor.idProduct); 199 200 /* 201 * If one of the devices below is present attached as a sibling of 202 * the touch controller then this is a newer IBM 4820 monitor that 203 * does not need the IBM-requested workaround if fw level is 204 * 0x010d - aka 'M'. 205 * No other HW can have this combination. 206 */ 207 if (child_vid==0x04b3) { 208 switch (child_pid) { 209 case 0x4676: /* 4820 21x Video */ 210 case 0x4677: /* 4820 51x Video */ 211 case 0x4678: /* 4820 2Lx Video */ 212 case 0x4679: /* 4820 5Lx Video */ 213 return false; 214 } 215 } 216 } 217 return true; 218 } 219 220 static int elo_probe(struct hid_device *hdev, const struct hid_device_id *id) 221 { 222 struct elo_priv *priv; 223 int ret; 224 225 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 226 if (!priv) 227 return -ENOMEM; 228 229 INIT_DELAYED_WORK(&priv->work, elo_work); 230 priv->usbdev = interface_to_usbdev(to_usb_interface(hdev->dev.parent)); 231 232 hid_set_drvdata(hdev, priv); 233 234 ret = hid_parse(hdev); 235 if (ret) { 236 hid_err(hdev, "parse failed\n"); 237 goto err_free; 238 } 239 240 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); 241 if (ret) { 242 hid_err(hdev, "hw start failed\n"); 243 goto err_free; 244 } 245 246 if (elo_broken_firmware(priv->usbdev)) { 247 hid_info(hdev, "broken firmware found, installing workaround\n"); 248 queue_delayed_work(wq, &priv->work, ELO_PERIODIC_READ_INTERVAL); 249 } 250 251 return 0; 252 err_free: 253 kfree(priv); 254 return ret; 255 } 256 257 static void elo_remove(struct hid_device *hdev) 258 { 259 struct elo_priv *priv = hid_get_drvdata(hdev); 260 261 hid_hw_stop(hdev); 262 flush_workqueue(wq); 263 kfree(priv); 264 } 265 266 static const struct hid_device_id elo_devices[] = { 267 { HID_USB_DEVICE(USB_VENDOR_ID_ELO, 0x0009), }, 268 { HID_USB_DEVICE(USB_VENDOR_ID_ELO, 0x0030), }, 269 { } 270 }; 271 MODULE_DEVICE_TABLE(hid, elo_devices); 272 273 static struct hid_driver elo_driver = { 274 .name = "elo", 275 .id_table = elo_devices, 276 .probe = elo_probe, 277 .remove = elo_remove, 278 .raw_event = elo_raw_event, 279 .input_configured = elo_input_configured, 280 }; 281 282 static int __init elo_driver_init(void) 283 { 284 int ret; 285 286 wq = create_singlethread_workqueue("elousb"); 287 if (!wq) 288 return -ENOMEM; 289 290 ret = hid_register_driver(&elo_driver); 291 if (ret) 292 destroy_workqueue(wq); 293 294 return ret; 295 } 296 module_init(elo_driver_init); 297 298 static void __exit elo_driver_exit(void) 299 { 300 hid_unregister_driver(&elo_driver); 301 destroy_workqueue(wq); 302 } 303 module_exit(elo_driver_exit); 304 305 MODULE_AUTHOR("Jiri Slaby <jslaby@suse.cz>"); 306 MODULE_LICENSE("GPL"); 307