diff options
Diffstat (limited to 'drivers/hid/hid-multitouch.c')
-rw-r--r-- | drivers/hid/hid-multitouch.c | 48 |
1 files changed, 34 insertions, 14 deletions
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 346e9caef6f3..a4a274ebfbef 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -665,7 +665,8 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi, /* * Model touchscreens providing buttons as touchpads. */ - if ((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON) { + if (field->application == HID_DG_TOUCHSCREEN && + (usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON) { app->mt_flags |= INPUT_MT_POINTER; td->inputmode_value = MT_INPUTMODE_TOUCHPAD; } @@ -692,6 +693,19 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi, set_abs(hi->input, code, field, cls->sn_move); + /* + * A system multi-axis that exports X and Y has a high + * chance of being used directly on a surface + */ + if (field->application == HID_GD_SYSTEM_MULTIAXIS) { + __set_bit(INPUT_PROP_DIRECT, + hi->input->propbit); + input_set_abs_params(hi->input, + ABS_MT_TOOL_TYPE, + MT_TOOL_DIAL, + MT_TOOL_DIAL, 0, 0); + } + return 1; case HID_GD_Y: if (prev_usage && (prev_usage->hid == usage->hid)) { @@ -725,7 +739,9 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi, MT_STORE_FIELD(confidence_state); return 1; case HID_DG_TIPSWITCH: - input_set_capability(hi->input, EV_KEY, BTN_TOUCH); + if (field->application != HID_GD_SYSTEM_MULTIAXIS) + input_set_capability(hi->input, + EV_KEY, BTN_TOUCH); MT_STORE_FIELD(tip_state); return 1; case HID_DG_CONTACTID: @@ -802,6 +818,10 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi, field->application == HID_DG_TOUCHPAD && (usage->hid & HID_USAGE) > 1) code--; + + if (field->application == HID_GD_SYSTEM_MULTIAXIS) + code = BTN_0 + ((usage->hid - 1) & HID_USAGE); + hid_map_usage(hi, usage, bit, max, EV_KEY, code); input_set_capability(hi->input, EV_KEY, code); return 1; @@ -899,6 +919,7 @@ static int mt_process_slot(struct mt_device *td, struct input_dev *input, bool inrange_state = false; int active; int slotnum; + int tool = MT_TOOL_FINGER; if (!slot) return -EINVAL; @@ -939,8 +960,11 @@ static int mt_process_slot(struct mt_device *td, struct input_dev *input, active = (*slot->tip_state || inrange_state) && confidence_state; + if (app->application == HID_GD_SYSTEM_MULTIAXIS) + tool = MT_TOOL_DIAL; + input_mt_slot(input, slotnum); - input_mt_report_slot_state(input, MT_TOOL_FINGER, active); + input_mt_report_slot_state(input, tool, active); if (active) { /* this finger is in proximity of the sensor */ int wide = (*slot->w > *slot->h); @@ -1203,6 +1227,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, field->application != HID_GD_SYSTEM_CONTROL && field->application != HID_CP_CONSUMER_CONTROL && field->application != HID_GD_WIRELESS_RADIO_CTLS && + field->application != HID_GD_SYSTEM_MULTIAXIS && !(field->application == HID_VD_ASUS_CUSTOM_MEDIA_KEYS && application->quirks & MT_QUIRK_ASUS_CUSTOM_UP)) return -1; @@ -1230,9 +1255,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, return 1; } - if (rdata->is_mt_collection && - (field->application == HID_DG_TOUCHSCREEN || - field->application == HID_DG_TOUCHPAD)) + if (rdata->is_mt_collection) return mt_touch_input_mapping(hdev, hi, field, usage, bit, max, application); @@ -1244,15 +1267,11 @@ static int mt_input_mapped(struct hid_device *hdev, struct hid_input *hi, struct hid_field *field, struct hid_usage *usage, unsigned long **bit, int *max) { - /* - * some egalax touchscreens have "application == HID_DG_TOUCHSCREEN" - * for the stylus. - */ - if (field->physical == HID_DG_STYLUS) - return 0; + struct mt_device *td = hid_get_drvdata(hdev); + struct mt_report_data *rdata; - if (field->application == HID_DG_TOUCHSCREEN || - field->application == HID_DG_TOUCHPAD) { + rdata = mt_find_report_data(td, field->report); + if (rdata && rdata->is_mt_collection) { /* We own these mappings, tell hid-input to ignore them */ return -1; } @@ -1460,6 +1479,7 @@ static int mt_input_configured(struct hid_device *hdev, struct hid_input *hi) case HID_GD_SYSTEM_CONTROL: case HID_CP_CONSUMER_CONTROL: case HID_GD_WIRELESS_RADIO_CTLS: + case HID_GD_SYSTEM_MULTIAXIS: /* already handled by hid core */ break; case HID_DG_TOUCHSCREEN: |