aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Tissoires <benjamin.tissoires@redhat.com>2014-09-23 12:08:09 -0400
committerJiri Kosina <jkosina@suse.cz>2014-10-01 03:11:23 -0400
commit5ae6e89f7409cb5d218bb728326eba9c650d9700 (patch)
treee3e1bac35f9c42c6a68666f7a802cf9b654bb607
parent7704ac937345d4b502062952657027234aa86a37 (diff)
HID: wacom: implement the finger part of the HID generic handling
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> Acked-by: Jason Gerecke <killertofu@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r--drivers/hid/wacom_sys.c39
-rw-r--r--drivers/hid/wacom_wac.c120
-rw-r--r--drivers/hid/wacom_wac.h8
3 files changed, 164 insertions, 3 deletions
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
index dd288b2fbfe8..8593047bb726 100644
--- a/drivers/hid/wacom_sys.c
+++ b/drivers/hid/wacom_sys.c
@@ -109,6 +109,7 @@ static void wacom_feature_mapping(struct hid_device *hdev,
109{ 109{
110 struct wacom *wacom = hid_get_drvdata(hdev); 110 struct wacom *wacom = hid_get_drvdata(hdev);
111 struct wacom_features *features = &wacom->wacom_wac.features; 111 struct wacom_features *features = &wacom->wacom_wac.features;
112 struct hid_data *hid_data = &wacom->wacom_wac.hid_data;
112 u8 *data; 113 u8 *data;
113 int ret; 114 int ret;
114 115
@@ -128,6 +129,16 @@ static void wacom_feature_mapping(struct hid_device *hdev,
128 kfree(data); 129 kfree(data);
129 } 130 }
130 break; 131 break;
132 case HID_DG_INPUTMODE:
133 /* Ignore if value index is out of bounds. */
134 if (usage->usage_index >= field->report_count) {
135 dev_err(&hdev->dev, "HID_DG_INPUTMODE out of range\n");
136 break;
137 }
138
139 hid_data->inputmode = field->report->id;
140 hid_data->inputmode_index = usage->usage_index;
141 break;
131 } 142 }
132} 143}
133 144
@@ -255,6 +266,25 @@ static void wacom_parse_hid(struct hid_device *hdev,
255 } 266 }
256} 267}
257 268
269static int wacom_hid_set_device_mode(struct hid_device *hdev)
270{
271 struct wacom *wacom = hid_get_drvdata(hdev);
272 struct hid_data *hid_data = &wacom->wacom_wac.hid_data;
273 struct hid_report *r;
274 struct hid_report_enum *re;
275
276 if (hid_data->inputmode < 0)
277 return 0;
278
279 re = &(hdev->report_enum[HID_FEATURE_REPORT]);
280 r = re->report_id_hash[hid_data->inputmode];
281 if (r) {
282 r->field[0]->value[hid_data->inputmode_index] = 2;
283 hid_hw_request(hdev, r, HID_REQ_SET_REPORT);
284 }
285 return 0;
286}
287
258static int wacom_set_device_mode(struct hid_device *hdev, int report_id, 288static int wacom_set_device_mode(struct hid_device *hdev, int report_id,
259 int length, int mode) 289 int length, int mode)
260{ 290{
@@ -347,6 +377,9 @@ static int wacom_query_tablet_data(struct hid_device *hdev,
347 if (hdev->bus == BUS_BLUETOOTH) 377 if (hdev->bus == BUS_BLUETOOTH)
348 return wacom_bt_query_tablet_data(hdev, 1, features); 378 return wacom_bt_query_tablet_data(hdev, 1, features);
349 379
380 if (features->type == HID_GENERIC)
381 return wacom_hid_set_device_mode(hdev);
382
350 if (features->device_type == BTN_TOOL_FINGER) { 383 if (features->device_type == BTN_TOOL_FINGER) {
351 if (features->type > TABLETPC) { 384 if (features->type > TABLETPC) {
352 /* MT Tablet PC touch */ 385 /* MT Tablet PC touch */
@@ -1451,9 +1484,6 @@ static int wacom_probe(struct hid_device *hdev,
1451 error); 1484 error);
1452 } 1485 }
1453 1486
1454 /* Note that if query fails it is not a hard failure */
1455 wacom_query_tablet_data(hdev, features);
1456
1457 if (features->type == HID_GENERIC) 1487 if (features->type == HID_GENERIC)
1458 connect_mask |= HID_CONNECT_DRIVER; 1488 connect_mask |= HID_CONNECT_DRIVER;
1459 1489
@@ -1464,6 +1494,9 @@ static int wacom_probe(struct hid_device *hdev,
1464 goto fail_hw_start; 1494 goto fail_hw_start;
1465 } 1495 }
1466 1496
1497 /* Note that if query fails it is not a hard failure */
1498 wacom_query_tablet_data(hdev, features);
1499
1467 if (features->quirks & WACOM_QUIRK_MONITOR) 1500 if (features->quirks & WACOM_QUIRK_MONITOR)
1468 error = hid_hw_open(hdev); 1501 error = hid_hw_open(hdev);
1469 1502
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index e77d46d85a11..586b2405b0d4 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -1372,6 +1372,117 @@ static void wacom_wac_pen_report(struct hid_device *hdev,
1372 } 1372 }
1373} 1373}
1374 1374
1375static void wacom_wac_finger_usage_mapping(struct hid_device *hdev,
1376 struct hid_field *field, struct hid_usage *usage)
1377{
1378 struct wacom *wacom = hid_get_drvdata(hdev);
1379 struct wacom_wac *wacom_wac = &wacom->wacom_wac;
1380 struct input_dev *input = wacom_wac->input;
1381 unsigned touch_max = wacom_wac->features.touch_max;
1382
1383 switch (usage->hid) {
1384 case HID_GD_X:
1385 if (touch_max == 1)
1386 wacom_map_usage(wacom, usage, field, EV_ABS, ABS_X, 4);
1387 else
1388 wacom_map_usage(wacom, usage, field, EV_ABS,
1389 ABS_MT_POSITION_X, 4);
1390 break;
1391 case HID_GD_Y:
1392 if (touch_max == 1)
1393 wacom_map_usage(wacom, usage, field, EV_ABS, ABS_Y, 4);
1394 else
1395 wacom_map_usage(wacom, usage, field, EV_ABS,
1396 ABS_MT_POSITION_Y, 4);
1397 break;
1398 case HID_DG_CONTACTID:
1399 input_mt_init_slots(input, wacom_wac->features.touch_max,
1400 INPUT_MT_DIRECT);
1401 break;
1402 case HID_DG_INRANGE:
1403 break;
1404 case HID_DG_INVERT:
1405 break;
1406 case HID_DG_TIPSWITCH:
1407 wacom_map_usage(wacom, usage, field, EV_KEY, BTN_TOUCH, 0);
1408 break;
1409 }
1410}
1411
1412static int wacom_wac_finger_event(struct hid_device *hdev,
1413 struct hid_field *field, struct hid_usage *usage, __s32 value)
1414{
1415 struct wacom *wacom = hid_get_drvdata(hdev);
1416 struct wacom_wac *wacom_wac = &wacom->wacom_wac;
1417
1418 switch (usage->hid) {
1419 case HID_GD_X:
1420 wacom_wac->hid_data.x = value;
1421 break;
1422 case HID_GD_Y:
1423 wacom_wac->hid_data.y = value;
1424 break;
1425 case HID_DG_CONTACTID:
1426 wacom_wac->hid_data.id = value;
1427 break;
1428 case HID_DG_TIPSWITCH:
1429 wacom_wac->hid_data.tipswitch = value;
1430 break;
1431 }
1432
1433
1434 return 0;
1435}
1436
1437static void wacom_wac_finger_mt_report(struct wacom_wac *wacom_wac,
1438 struct input_dev *input, bool touch)
1439{
1440 int slot;
1441 struct hid_data *hid_data = &wacom_wac->hid_data;
1442
1443 slot = input_mt_get_slot_by_key(input, hid_data->id);
1444
1445 input_mt_slot(input, slot);
1446 input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);
1447 if (touch) {
1448 input_report_abs(input, ABS_MT_POSITION_X, hid_data->x);
1449 input_report_abs(input, ABS_MT_POSITION_Y, hid_data->y);
1450 }
1451 input_mt_sync_frame(input);
1452}
1453
1454static void wacom_wac_finger_single_touch_report(struct wacom_wac *wacom_wac,
1455 struct input_dev *input, bool touch)
1456{
1457 struct hid_data *hid_data = &wacom_wac->hid_data;
1458
1459 if (touch) {
1460 input_report_abs(input, ABS_X, hid_data->x);
1461 input_report_abs(input, ABS_Y, hid_data->y);
1462 }
1463 input_report_key(input, BTN_TOUCH, touch);
1464}
1465
1466static void wacom_wac_finger_report(struct hid_device *hdev,
1467 struct hid_report *report)
1468{
1469 struct wacom *wacom = hid_get_drvdata(hdev);
1470 struct wacom_wac *wacom_wac = &wacom->wacom_wac;
1471 struct input_dev *input = wacom_wac->input;
1472 bool touch = wacom_wac->hid_data.tipswitch &&
1473 !wacom_wac->shared->stylus_in_proximity;
1474 unsigned touch_max = wacom_wac->features.touch_max;
1475
1476 if (touch_max > 1)
1477 wacom_wac_finger_mt_report(wacom_wac, input, touch);
1478 else
1479 wacom_wac_finger_single_touch_report(wacom_wac, input, touch);
1480 input_sync(input);
1481
1482 /* keep touch state for pen event */
1483 wacom_wac->shared->touch_down = touch;
1484}
1485
1375#define WACOM_PEN_FIELD(f) (((f)->logical == HID_DG_STYLUS) || \ 1486#define WACOM_PEN_FIELD(f) (((f)->logical == HID_DG_STYLUS) || \
1376 ((f)->physical == HID_DG_STYLUS)) 1487 ((f)->physical == HID_DG_STYLUS))
1377#define WACOM_FINGER_FIELD(f) (((f)->logical == HID_DG_FINGER) || \ 1488#define WACOM_FINGER_FIELD(f) (((f)->logical == HID_DG_FINGER) || \
@@ -1389,6 +1500,9 @@ void wacom_wac_usage_mapping(struct hid_device *hdev,
1389 1500
1390 if (WACOM_PEN_FIELD(field)) 1501 if (WACOM_PEN_FIELD(field))
1391 return wacom_wac_pen_usage_mapping(hdev, field, usage); 1502 return wacom_wac_pen_usage_mapping(hdev, field, usage);
1503
1504 if (WACOM_FINGER_FIELD(field))
1505 return wacom_wac_finger_usage_mapping(hdev, field, usage);
1392} 1506}
1393 1507
1394int wacom_wac_event(struct hid_device *hdev, struct hid_field *field, 1508int wacom_wac_event(struct hid_device *hdev, struct hid_field *field,
@@ -1402,6 +1516,9 @@ int wacom_wac_event(struct hid_device *hdev, struct hid_field *field,
1402 if (WACOM_PEN_FIELD(field)) 1516 if (WACOM_PEN_FIELD(field))
1403 return wacom_wac_pen_event(hdev, field, usage, value); 1517 return wacom_wac_pen_event(hdev, field, usage, value);
1404 1518
1519 if (WACOM_FINGER_FIELD(field))
1520 return wacom_wac_finger_event(hdev, field, usage, value);
1521
1405 return 0; 1522 return 0;
1406} 1523}
1407 1524
@@ -1416,6 +1533,9 @@ void wacom_wac_report(struct hid_device *hdev, struct hid_report *report)
1416 1533
1417 if (WACOM_PEN_FIELD(field)) 1534 if (WACOM_PEN_FIELD(field))
1418 return wacom_wac_pen_report(hdev, report); 1535 return wacom_wac_pen_report(hdev, report);
1536
1537 if (WACOM_FINGER_FIELD(field))
1538 return wacom_wac_finger_report(hdev, report);
1419} 1539}
1420 1540
1421static int wacom_bpt_touch(struct wacom_wac *wacom) 1541static int wacom_bpt_touch(struct wacom_wac *wacom)
diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h
index f472eac292d5..0f0b85ec1322 100644
--- a/drivers/hid/wacom_wac.h
+++ b/drivers/hid/wacom_wac.h
@@ -156,9 +156,17 @@ struct wacom_shared {
156}; 156};
157 157
158struct hid_data { 158struct hid_data {
159 __s16 inputmode; /* InputMode HID feature, -1 if non-existent */
160 __s16 inputmode_index; /* InputMode HID feature index in the report */
159 bool inrange_state; 161 bool inrange_state;
160 bool invert_state; 162 bool invert_state;
161 bool tipswitch; 163 bool tipswitch;
164 int x;
165 int y;
166 int pressure;
167 int width;
168 int height;
169 int id;
162}; 170};
163 171
164struct wacom_wac { 172struct wacom_wac {