1/* 2 * Bluetooth Wacom Tablet support 3 * 4 * Copyright (c) 1999 Andreas Gal 5 * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> 6 * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc 7 * Copyright (c) 2006-2007 Jiri Kosina 8 * Copyright (c) 2007 Paul Walmsley 9 * Copyright (c) 2008 Jiri Slaby <jirislaby@gmail.com> 10 * Copyright (c) 2006 Andrew Zabolotny <zap@homelink.ru> 11 * Copyright (c) 2009 Bastien Nocera <hadess@hadess.net> 12 */ 13 14/* 15 * This program is free software; you can redistribute it and/or modify it 16 * under the terms of the GNU General Public License as published by the Free 17 * Software Foundation; either version 2 of the License, or (at your option) 18 * any later version. 19 */ 20 21#include <linux/device.h> 22#include <linux/hid.h> 23#include <linux/module.h> 24#include <linux/slab.h> 25#ifdef CONFIG_HID_WACOM_POWER_SUPPLY 26#include <linux/power_supply.h> 27#endif 28 29#include "hid-ids.h" 30 31struct wacom_data { 32 __u16 tool; 33 unsigned char butstate; 34 unsigned char high_speed; 35#ifdef CONFIG_HID_WACOM_POWER_SUPPLY 36 int battery_capacity; 37 struct power_supply battery; 38 struct power_supply ac; 39#endif 40}; 41 42#ifdef CONFIG_HID_WACOM_POWER_SUPPLY 43/*percent of battery capacity, 0 means AC online*/ 44static unsigned short batcap[8] = { 1, 15, 25, 35, 50, 70, 100, 0 }; 45 46static enum power_supply_property wacom_battery_props[] = { 47 POWER_SUPPLY_PROP_PRESENT, 48 POWER_SUPPLY_PROP_CAPACITY 49}; 50 51static enum power_supply_property wacom_ac_props[] = { 52 POWER_SUPPLY_PROP_PRESENT, 53 POWER_SUPPLY_PROP_ONLINE 54}; 55 56static int wacom_battery_get_property(struct power_supply *psy, 57 enum power_supply_property psp, 58 union power_supply_propval *val) 59{ 60 struct wacom_data *wdata = container_of(psy, 61 struct wacom_data, battery); 62 int power_state = batcap[wdata->battery_capacity]; 63 int ret = 0; 64 65 switch (psp) { 66 case POWER_SUPPLY_PROP_PRESENT: 67 val->intval = 1; 68 break; 69 case POWER_SUPPLY_PROP_CAPACITY: 70 /* show 100% battery capacity when charging */ 71 if (power_state == 0) 72 val->intval = 100; 73 else 74 val->intval = power_state; 75 break; 76 default: 77 ret = -EINVAL; 78 break; 79 } 80 return ret; 81} 82 83static int wacom_ac_get_property(struct power_supply *psy, 84 enum power_supply_property psp, 85 union power_supply_propval *val) 86{ 87 struct wacom_data *wdata = container_of(psy, struct wacom_data, ac); 88 int power_state = batcap[wdata->battery_capacity]; 89 int ret = 0; 90 91 switch (psp) { 92 case POWER_SUPPLY_PROP_PRESENT: 93 /* fall through */ 94 case POWER_SUPPLY_PROP_ONLINE: 95 if (power_state == 0) 96 val->intval = 1; 97 else 98 val->intval = 0; 99 break; 100 default: 101 ret = -EINVAL; 102 break; 103 } 104 return ret; 105} 106#endif 107 108static void wacom_poke(struct hid_device *hdev, u8 speed) 109{ 110 struct wacom_data *wdata = hid_get_drvdata(hdev); 111 int limit, ret; 112 char rep_data[2]; 113 114 rep_data[0] = 0x03 ; rep_data[1] = 0x00; 115 limit = 3; 116 do { 117 ret = hdev->hid_output_raw_report(hdev, rep_data, 2, 118 HID_FEATURE_REPORT); 119 } while (ret < 0 && limit-- > 0); 120 121 if (ret >= 0) { 122 if (speed == 0) 123 rep_data[0] = 0x05; 124 else 125 rep_data[0] = 0x06; 126 127 rep_data[1] = 0x00; 128 limit = 3; 129 do { 130 ret = hdev->hid_output_raw_report(hdev, rep_data, 2, 131 HID_FEATURE_REPORT); 132 } while (ret < 0 && limit-- > 0); 133 134 if (ret >= 0) { 135 wdata->high_speed = speed; 136 return; 137 } 138 } 139 140 /* 141 * Note that if the raw queries fail, it's not a hard failure and it 142 * is safe to continue 143 */ 144 dev_warn(&hdev->dev, "failed to poke device, command %d, err %d\n", 145 rep_data[0], ret); 146 return; 147} 148 149static ssize_t wacom_show_speed(struct device *dev, 150 struct device_attribute 151 *attr, char *buf) 152{ 153 struct wacom_data *wdata = dev_get_drvdata(dev); 154 155 return snprintf(buf, PAGE_SIZE, "%i\n", wdata->high_speed); 156} 157 158static ssize_t wacom_store_speed(struct device *dev, 159 struct device_attribute *attr, 160 const char *buf, size_t count) 161{ 162 struct hid_device *hdev = container_of(dev, struct hid_device, dev); 163 int new_speed; 164 165 if (sscanf(buf, "%1d", &new_speed ) != 1) 166 return -EINVAL; 167 168 if (new_speed == 0 || new_speed == 1) { 169 wacom_poke(hdev, new_speed); 170 return strnlen(buf, PAGE_SIZE); 171 } else 172 return -EINVAL; 173} 174 175static DEVICE_ATTR(speed, S_IRUGO | S_IWUGO, 176 wacom_show_speed, wacom_store_speed); 177 178static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report, 179 u8 *raw_data, int size) 180{ 181 struct wacom_data *wdata = hid_get_drvdata(hdev); 182 struct hid_input *hidinput; 183 struct input_dev *input; 184 unsigned char *data = (unsigned char *) raw_data; 185 int tool, x, y, rw; 186 187 if (!(hdev->claimed & HID_CLAIMED_INPUT)) 188 return 0; 189 190 tool = 0; 191 hidinput = list_entry(hdev->inputs.next, struct hid_input, list); 192 input = hidinput->input; 193 194 /* Check if this is a tablet report */ 195 if (data[0] != 0x03) 196 return 0; 197 198 /* Get X & Y positions */ 199 x = le16_to_cpu(*(__le16 *) &data[2]); 200 y = le16_to_cpu(*(__le16 *) &data[4]); 201 202 /* Get current tool identifier */ 203 if (data[1] & 0x90) { /* If pen is in the in/active area */ 204 switch ((data[1] >> 5) & 3) { 205 case 0: /* Pen */ 206 tool = BTN_TOOL_PEN; 207 break; 208 209 case 1: /* Rubber */ 210 tool = BTN_TOOL_RUBBER; 211 break; 212 213 case 2: /* Mouse with wheel */ 214 case 3: /* Mouse without wheel */ 215 tool = BTN_TOOL_MOUSE; 216 break; 217 } 218 219 /* Reset tool if out of active tablet area */ 220 if (!(data[1] & 0x10)) 221 tool = 0; 222 } 223 224 /* If tool changed, notify input subsystem */ 225 if (wdata->tool != tool) { 226 if (wdata->tool) { 227 /* Completely reset old tool state */ 228 if (wdata->tool == BTN_TOOL_MOUSE) { 229 input_report_key(input, BTN_LEFT, 0); 230 input_report_key(input, BTN_RIGHT, 0); 231 input_report_key(input, BTN_MIDDLE, 0); 232 input_report_abs(input, ABS_DISTANCE, 233 input_abs_get_max(input, ABS_DISTANCE)); 234 } else { 235 input_report_key(input, BTN_TOUCH, 0); 236 input_report_key(input, BTN_STYLUS, 0); 237 input_report_key(input, BTN_STYLUS2, 0); 238 input_report_abs(input, ABS_PRESSURE, 0); 239 } 240 input_report_key(input, wdata->tool, 0); 241 input_sync(input); 242 } 243 wdata->tool = tool; 244 if (tool) 245 input_report_key(input, tool, 1); 246 } 247 248 if (tool) { 249 input_report_abs(input, ABS_X, x); 250 input_report_abs(input, ABS_Y, y); 251 252 switch ((data[1] >> 5) & 3) { 253 case 2: /* Mouse with wheel */ 254 input_report_key(input, BTN_MIDDLE, data[1] & 0x04); 255 rw = (data[6] & 0x01) ? -1 : 256 (data[6] & 0x02) ? 1 : 0; 257 input_report_rel(input, REL_WHEEL, rw); 258 /* fall through */ 259 260 case 3: /* Mouse without wheel */ 261 input_report_key(input, BTN_LEFT, data[1] & 0x01); 262 input_report_key(input, BTN_RIGHT, data[1] & 0x02); 263 /* Compute distance between mouse and tablet */ 264 rw = 44 - (data[6] >> 2); 265 if (rw < 0) 266 rw = 0; 267 else if (rw > 31) 268 rw = 31; 269 input_report_abs(input, ABS_DISTANCE, rw); 270 break; 271 272 default: 273 input_report_abs(input, ABS_PRESSURE, 274 data[6] | (((__u16) (data[1] & 0x08)) << 5)); 275 input_report_key(input, BTN_TOUCH, data[1] & 0x01); 276 input_report_key(input, BTN_STYLUS, data[1] & 0x02); 277 input_report_key(input, BTN_STYLUS2, (tool == BTN_TOOL_PEN) && data[1] & 0x04); 278 break; 279 } 280 281 input_sync(input); 282 } 283 284 /* Report the state of the two buttons at the top of the tablet 285 * as two extra fingerpad keys (buttons 4 & 5). */ 286 rw = data[7] & 0x03; 287 if (rw != wdata->butstate) { 288 wdata->butstate = rw; 289 input_report_key(input, BTN_0, rw & 0x02); 290 input_report_key(input, BTN_1, rw & 0x01); 291 input_report_key(input, BTN_TOOL_FINGER, 0xf0); 292 input_event(input, EV_MSC, MSC_SERIAL, 0xf0); 293 input_sync(input); 294 } 295 296#ifdef CONFIG_HID_WACOM_POWER_SUPPLY 297 /* Store current battery capacity */ 298 rw = (data[7] >> 2 & 0x07); 299 if (rw != wdata->battery_capacity) 300 wdata->battery_capacity = rw; 301#endif 302 return 1; 303} 304 305static int wacom_probe(struct hid_device *hdev, 306 const struct hid_device_id *id) 307{ 308 struct hid_input *hidinput; 309 struct input_dev *input; 310 struct wacom_data *wdata; 311 int ret; 312 313 wdata = kzalloc(sizeof(*wdata), GFP_KERNEL); 314 if (wdata == NULL) { 315 dev_err(&hdev->dev, "can't alloc wacom descriptor\n"); 316 return -ENOMEM; 317 } 318 319 hid_set_drvdata(hdev, wdata); 320 321 /* Parse the HID report now */ 322 ret = hid_parse(hdev); 323 if (ret) { 324 dev_err(&hdev->dev, "parse failed\n"); 325 goto err_free; 326 } 327 328 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); 329 if (ret) { 330 dev_err(&hdev->dev, "hw start failed\n"); 331 goto err_free; 332 } 333 334 ret = device_create_file(&hdev->dev, &dev_attr_speed); 335 if (ret) 336 dev_warn(&hdev->dev, 337 "can't create sysfs speed attribute err: %d\n", ret); 338 339 /* Set Wacom mode 2 with high reporting speed */ 340 wacom_poke(hdev, 1); 341 342#ifdef CONFIG_HID_WACOM_POWER_SUPPLY 343 wdata->battery.properties = wacom_battery_props; 344 wdata->battery.num_properties = ARRAY_SIZE(wacom_battery_props); 345 wdata->battery.get_property = wacom_battery_get_property; 346 wdata->battery.name = "wacom_battery"; 347 wdata->battery.type = POWER_SUPPLY_TYPE_BATTERY; 348 wdata->battery.use_for_apm = 0; 349 350 ret = power_supply_register(&hdev->dev, &wdata->battery); 351 if (ret) { 352 dev_warn(&hdev->dev, 353 "can't create sysfs battery attribute, err: %d\n", ret); 354 /* 355 * battery attribute is not critical for the tablet, but if it 356 * failed then there is no need to create ac attribute 357 */ 358 goto move_on; 359 } 360 361 wdata->ac.properties = wacom_ac_props; 362 wdata->ac.num_properties = ARRAY_SIZE(wacom_ac_props); 363 wdata->ac.get_property = wacom_ac_get_property; 364 wdata->ac.name = "wacom_ac"; 365 wdata->ac.type = POWER_SUPPLY_TYPE_MAINS; 366 wdata->ac.use_for_apm = 0; 367 368 ret = power_supply_register(&hdev->dev, &wdata->ac); 369 if (ret) { 370 dev_warn(&hdev->dev, 371 "can't create ac battery attribute, err: %d\n", ret); 372 /* 373 * ac attribute is not critical for the tablet, but if it 374 * failed then we don't want to battery attribute to exist 375 */ 376 power_supply_unregister(&wdata->battery); 377 } 378 379move_on: 380#endif 381 hidinput = list_entry(hdev->inputs.next, struct hid_input, list); 382 input = hidinput->input; 383 384 /* Basics */ 385 input->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_REL); 386 387 __set_bit(REL_WHEEL, input->relbit); 388 389 __set_bit(BTN_TOOL_PEN, input->keybit); 390 __set_bit(BTN_TOUCH, input->keybit); 391 __set_bit(BTN_STYLUS, input->keybit); 392 __set_bit(BTN_STYLUS2, input->keybit); 393 __set_bit(BTN_LEFT, input->keybit); 394 __set_bit(BTN_RIGHT, input->keybit); 395 __set_bit(BTN_MIDDLE, input->keybit); 396 397 /* Pad */ 398 input->evbit[0] |= BIT(EV_MSC); 399 400 __set_bit(MSC_SERIAL, input->mscbit); 401 402 __set_bit(BTN_0, input->keybit); 403 __set_bit(BTN_1, input->keybit); 404 __set_bit(BTN_TOOL_FINGER, input->keybit); 405 406 /* Distance, rubber and mouse */ 407 __set_bit(BTN_TOOL_RUBBER, input->keybit); 408 __set_bit(BTN_TOOL_MOUSE, input->keybit); 409 410 input_set_abs_params(input, ABS_X, 0, 16704, 4, 0); 411 input_set_abs_params(input, ABS_Y, 0, 12064, 4, 0); 412 input_set_abs_params(input, ABS_PRESSURE, 0, 511, 0, 0); 413 input_set_abs_params(input, ABS_DISTANCE, 0, 32, 0, 0); 414 415 return 0; 416 417err_free: 418 kfree(wdata); 419 return ret; 420} 421 422static void wacom_remove(struct hid_device *hdev) 423{ 424#ifdef CONFIG_HID_WACOM_POWER_SUPPLY 425 struct wacom_data *wdata = hid_get_drvdata(hdev); 426#endif 427 hid_hw_stop(hdev); 428 429#ifdef CONFIG_HID_WACOM_POWER_SUPPLY 430 power_supply_unregister(&wdata->battery); 431 power_supply_unregister(&wdata->ac); 432#endif 433 kfree(hid_get_drvdata(hdev)); 434} 435 436static const struct hid_device_id wacom_devices[] = { 437 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) }, 438 439 { } 440}; 441MODULE_DEVICE_TABLE(hid, wacom_devices); 442 443static struct hid_driver wacom_driver = { 444 .name = "wacom", 445 .id_table = wacom_devices, 446 .probe = wacom_probe, 447 .remove = wacom_remove, 448 .raw_event = wacom_raw_event, 449}; 450 451static int __init wacom_init(void) 452{ 453 int ret; 454 455 ret = hid_register_driver(&wacom_driver); 456 if (ret) 457 printk(KERN_ERR "can't register wacom driver\n"); 458 return ret; 459} 460 461static void __exit wacom_exit(void) 462{ 463 hid_unregister_driver(&wacom_driver); 464} 465 466module_init(wacom_init); 467module_exit(wacom_exit); 468MODULE_LICENSE("GPL"); 469