diff options
| -rw-r--r-- | drivers/hid/wacom.h | 5 | ||||
| -rw-r--r-- | drivers/hid/wacom_sys.c | 49 | ||||
| -rw-r--r-- | drivers/hid/wacom_wac.c | 17 | ||||
| -rw-r--r-- | drivers/hid/wacom_wac.h | 4 |
4 files changed, 74 insertions, 1 deletions
diff --git a/drivers/hid/wacom.h b/drivers/hid/wacom.h index 38ee2125412f..c7b9ab1907d8 100644 --- a/drivers/hid/wacom.h +++ b/drivers/hid/wacom.h | |||
| @@ -110,6 +110,7 @@ enum wacom_worker { | |||
| 110 | WACOM_WORKER_WIRELESS, | 110 | WACOM_WORKER_WIRELESS, |
| 111 | WACOM_WORKER_BATTERY, | 111 | WACOM_WORKER_BATTERY, |
| 112 | WACOM_WORKER_REMOTE, | 112 | WACOM_WORKER_REMOTE, |
| 113 | WACOM_WORKER_MODE_CHANGE, | ||
| 113 | }; | 114 | }; |
| 114 | 115 | ||
| 115 | struct wacom; | 116 | struct wacom; |
| @@ -167,6 +168,7 @@ struct wacom { | |||
| 167 | struct work_struct remote_work; | 168 | struct work_struct remote_work; |
| 168 | struct delayed_work init_work; | 169 | struct delayed_work init_work; |
| 169 | struct wacom_remote *remote; | 170 | struct wacom_remote *remote; |
| 171 | struct work_struct mode_change_work; | ||
| 170 | bool generic_has_leds; | 172 | bool generic_has_leds; |
| 171 | struct wacom_leds { | 173 | struct wacom_leds { |
| 172 | struct wacom_group_leds *groups; | 174 | struct wacom_group_leds *groups; |
| @@ -196,6 +198,9 @@ static inline void wacom_schedule_work(struct wacom_wac *wacom_wac, | |||
| 196 | case WACOM_WORKER_REMOTE: | 198 | case WACOM_WORKER_REMOTE: |
| 197 | schedule_work(&wacom->remote_work); | 199 | schedule_work(&wacom->remote_work); |
| 198 | break; | 200 | break; |
| 201 | case WACOM_WORKER_MODE_CHANGE: | ||
| 202 | schedule_work(&wacom->mode_change_work); | ||
| 203 | break; | ||
| 199 | } | 204 | } |
| 200 | } | 205 | } |
| 201 | 206 | ||
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index be8f7e2a026f..9aec5b3a45bd 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c | |||
| @@ -325,6 +325,13 @@ static void wacom_post_parse_hid(struct hid_device *hdev, | |||
| 325 | 325 | ||
| 326 | if (features->type == HID_GENERIC) { | 326 | if (features->type == HID_GENERIC) { |
| 327 | /* Any last-minute generic device setup */ | 327 | /* Any last-minute generic device setup */ |
| 328 | if (wacom_wac->has_mode_change) { | ||
| 329 | if (wacom_wac->is_direct_mode) | ||
| 330 | features->device_type |= WACOM_DEVICETYPE_DIRECT; | ||
| 331 | else | ||
| 332 | features->device_type &= ~WACOM_DEVICETYPE_DIRECT; | ||
| 333 | } | ||
| 334 | |||
| 328 | if (features->touch_max > 1) { | 335 | if (features->touch_max > 1) { |
| 329 | if (features->device_type & WACOM_DEVICETYPE_DIRECT) | 336 | if (features->device_type & WACOM_DEVICETYPE_DIRECT) |
| 330 | input_mt_init_slots(wacom_wac->touch_input, | 337 | input_mt_init_slots(wacom_wac->touch_input, |
| @@ -2488,6 +2495,46 @@ static void wacom_remote_work(struct work_struct *work) | |||
| 2488 | } | 2495 | } |
| 2489 | } | 2496 | } |
| 2490 | 2497 | ||
| 2498 | static void wacom_mode_change_work(struct work_struct *work) | ||
| 2499 | { | ||
| 2500 | struct wacom *wacom = container_of(work, struct wacom, mode_change_work); | ||
| 2501 | struct wacom_shared *shared = wacom->wacom_wac.shared; | ||
| 2502 | struct wacom *wacom1 = NULL; | ||
| 2503 | struct wacom *wacom2 = NULL; | ||
| 2504 | bool is_direct = wacom->wacom_wac.is_direct_mode; | ||
| 2505 | int error = 0; | ||
| 2506 | |||
| 2507 | if (shared->pen) { | ||
| 2508 | wacom1 = hid_get_drvdata(shared->pen); | ||
| 2509 | wacom_release_resources(wacom1); | ||
| 2510 | hid_hw_stop(wacom1->hdev); | ||
| 2511 | wacom1->wacom_wac.has_mode_change = true; | ||
| 2512 | wacom1->wacom_wac.is_direct_mode = is_direct; | ||
| 2513 | } | ||
| 2514 | |||
| 2515 | if (shared->touch) { | ||
| 2516 | wacom2 = hid_get_drvdata(shared->touch); | ||
| 2517 | wacom_release_resources(wacom2); | ||
| 2518 | hid_hw_stop(wacom2->hdev); | ||
| 2519 | wacom2->wacom_wac.has_mode_change = true; | ||
| 2520 | wacom2->wacom_wac.is_direct_mode = is_direct; | ||
| 2521 | } | ||
| 2522 | |||
| 2523 | if (wacom1) { | ||
| 2524 | error = wacom_parse_and_register(wacom1, false); | ||
| 2525 | if (error) | ||
| 2526 | return; | ||
| 2527 | } | ||
| 2528 | |||
| 2529 | if (wacom2) { | ||
| 2530 | error = wacom_parse_and_register(wacom2, false); | ||
| 2531 | if (error) | ||
| 2532 | return; | ||
| 2533 | } | ||
| 2534 | |||
| 2535 | return; | ||
| 2536 | } | ||
| 2537 | |||
| 2491 | static int wacom_probe(struct hid_device *hdev, | 2538 | static int wacom_probe(struct hid_device *hdev, |
| 2492 | const struct hid_device_id *id) | 2539 | const struct hid_device_id *id) |
| 2493 | { | 2540 | { |
| @@ -2532,6 +2579,7 @@ static int wacom_probe(struct hid_device *hdev, | |||
| 2532 | INIT_WORK(&wacom->wireless_work, wacom_wireless_work); | 2579 | INIT_WORK(&wacom->wireless_work, wacom_wireless_work); |
| 2533 | INIT_WORK(&wacom->battery_work, wacom_battery_work); | 2580 | INIT_WORK(&wacom->battery_work, wacom_battery_work); |
| 2534 | INIT_WORK(&wacom->remote_work, wacom_remote_work); | 2581 | INIT_WORK(&wacom->remote_work, wacom_remote_work); |
| 2582 | INIT_WORK(&wacom->mode_change_work, wacom_mode_change_work); | ||
| 2535 | 2583 | ||
| 2536 | /* ask for the report descriptor to be loaded by HID */ | 2584 | /* ask for the report descriptor to be loaded by HID */ |
| 2537 | error = hid_parse(hdev); | 2585 | error = hid_parse(hdev); |
| @@ -2574,6 +2622,7 @@ static void wacom_remove(struct hid_device *hdev) | |||
| 2574 | cancel_work_sync(&wacom->wireless_work); | 2622 | cancel_work_sync(&wacom->wireless_work); |
| 2575 | cancel_work_sync(&wacom->battery_work); | 2623 | cancel_work_sync(&wacom->battery_work); |
| 2576 | cancel_work_sync(&wacom->remote_work); | 2624 | cancel_work_sync(&wacom->remote_work); |
| 2625 | cancel_work_sync(&wacom->mode_change_work); | ||
| 2577 | if (hdev->bus == BUS_BLUETOOTH) | 2626 | if (hdev->bus == BUS_BLUETOOTH) |
| 2578 | device_remove_file(&hdev->dev, &dev_attr_speed); | 2627 | device_remove_file(&hdev->dev, &dev_attr_speed); |
| 2579 | 2628 | ||
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index dbda99272374..2c399a423957 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c | |||
| @@ -1780,6 +1780,14 @@ static void wacom_wac_pad_usage_mapping(struct hid_device *hdev, | |||
| 1780 | wacom_map_usage(input, usage, field, EV_KEY, KEY_CONTROLPANEL, 0); | 1780 | wacom_map_usage(input, usage, field, EV_KEY, KEY_CONTROLPANEL, 0); |
| 1781 | features->device_type |= WACOM_DEVICETYPE_PAD; | 1781 | features->device_type |= WACOM_DEVICETYPE_PAD; |
| 1782 | break; | 1782 | break; |
| 1783 | case WACOM_HID_WD_MODE_CHANGE: | ||
| 1784 | /* do not overwrite previous data */ | ||
| 1785 | if (!wacom_wac->has_mode_change) { | ||
| 1786 | wacom_wac->has_mode_change = true; | ||
| 1787 | wacom_wac->is_direct_mode = true; | ||
| 1788 | } | ||
| 1789 | features->device_type |= WACOM_DEVICETYPE_PAD; | ||
| 1790 | break; | ||
| 1783 | } | 1791 | } |
| 1784 | 1792 | ||
| 1785 | switch (equivalent_usage & 0xfffffff0) { | 1793 | switch (equivalent_usage & 0xfffffff0) { |
| @@ -1828,7 +1836,7 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field | |||
| 1828 | * Avoid reporting this event and setting inrange_state if this usage | 1836 | * Avoid reporting this event and setting inrange_state if this usage |
| 1829 | * hasn't been mapped. | 1837 | * hasn't been mapped. |
| 1830 | */ | 1838 | */ |
| 1831 | if (!usage->type) | 1839 | if (!usage->type && equivalent_usage != WACOM_HID_WD_MODE_CHANGE) |
| 1832 | return; | 1840 | return; |
| 1833 | 1841 | ||
| 1834 | if (wacom_equivalent_usage(field->physical) == HID_DG_TABLETFUNCTIONKEY) { | 1842 | if (wacom_equivalent_usage(field->physical) == HID_DG_TABLETFUNCTIONKEY) { |
| @@ -1850,6 +1858,13 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field | |||
| 1850 | } | 1858 | } |
| 1851 | break; | 1859 | break; |
| 1852 | 1860 | ||
| 1861 | case WACOM_HID_WD_MODE_CHANGE: | ||
| 1862 | if (wacom_wac->is_direct_mode != value) { | ||
| 1863 | wacom_wac->is_direct_mode = value; | ||
| 1864 | wacom_schedule_work(&wacom->wacom_wac, WACOM_WORKER_MODE_CHANGE); | ||
| 1865 | } | ||
| 1866 | break; | ||
| 1867 | |||
| 1853 | case WACOM_HID_WD_BUTTONCENTER: | 1868 | case WACOM_HID_WD_BUTTONCENTER: |
| 1854 | for (i = 0; i < wacom->led.count; i++) | 1869 | for (i = 0; i < wacom->led.count; i++) |
| 1855 | wacom_update_led(wacom, features->numbered_buttons, | 1870 | wacom_update_led(wacom, features->numbered_buttons, |
diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index 5eba31d6c46a..d9669c6116b7 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h | |||
| @@ -120,6 +120,7 @@ | |||
| 120 | #define WACOM_HID_WD_BATTERY_LEVEL (WACOM_HID_UP_WACOMDIGITIZER | 0x043b) | 120 | #define WACOM_HID_WD_BATTERY_LEVEL (WACOM_HID_UP_WACOMDIGITIZER | 0x043b) |
| 121 | #define WACOM_HID_WD_EXPRESSKEY00 (WACOM_HID_UP_WACOMDIGITIZER | 0x0910) | 121 | #define WACOM_HID_WD_EXPRESSKEY00 (WACOM_HID_UP_WACOMDIGITIZER | 0x0910) |
| 122 | #define WACOM_HID_WD_EXPRESSKEYCAP00 (WACOM_HID_UP_WACOMDIGITIZER | 0x0950) | 122 | #define WACOM_HID_WD_EXPRESSKEYCAP00 (WACOM_HID_UP_WACOMDIGITIZER | 0x0950) |
| 123 | #define WACOM_HID_WD_MODE_CHANGE (WACOM_HID_UP_WACOMDIGITIZER | 0x0980) | ||
| 123 | #define WACOM_HID_WD_CONTROLPANEL (WACOM_HID_UP_WACOMDIGITIZER | 0x0982) | 124 | #define WACOM_HID_WD_CONTROLPANEL (WACOM_HID_UP_WACOMDIGITIZER | 0x0982) |
| 124 | #define WACOM_HID_WD_ONSCREEN_KEYBOARD (WACOM_HID_UP_WACOMDIGITIZER | 0x0983) | 125 | #define WACOM_HID_WD_ONSCREEN_KEYBOARD (WACOM_HID_UP_WACOMDIGITIZER | 0x0983) |
| 125 | #define WACOM_HID_WD_BUTTONCONFIG (WACOM_HID_UP_WACOMDIGITIZER | 0x0986) | 126 | #define WACOM_HID_WD_BUTTONCONFIG (WACOM_HID_UP_WACOMDIGITIZER | 0x0986) |
| @@ -330,6 +331,9 @@ struct wacom_wac { | |||
| 330 | int mode_value; | 331 | int mode_value; |
| 331 | struct hid_data hid_data; | 332 | struct hid_data hid_data; |
| 332 | bool has_mute_touch_switch; | 333 | bool has_mute_touch_switch; |
| 334 | bool has_mode_change; | ||
| 335 | bool is_direct_mode; | ||
| 336 | |||
| 333 | }; | 337 | }; |
| 334 | 338 | ||
| 335 | #endif | 339 | #endif |
