aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/hid/wacom.h5
-rw-r--r--drivers/hid/wacom_sys.c49
-rw-r--r--drivers/hid/wacom_wac.c17
-rw-r--r--drivers/hid/wacom_wac.h4
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
115struct wacom; 116struct 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
2498static 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
2491static int wacom_probe(struct hid_device *hdev, 2538static 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