@@ -353,7 +353,7 @@ static int magicmouse_raw_event(struct hid_device *hdev,
input_report_rel(input, REL_Y, y);
} else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
input_report_key(input, BTN_MOUSE, clicks & 1);
- input_mt_report_pointer_emulation(input, true);
+ input_mt_report_pointer_emulation(input, true, false);
}
input_sync(input);
@@ -184,6 +184,7 @@ EXPORT_SYMBOL(input_mt_report_finger_count);
* input_mt_report_pointer_emulation() - common pointer emulation
* @dev: input device with allocated MT slots
* @use_count: report number of active contacts as finger count
+ * @hover: report ABS_DISTANCE as hover event
*
* Performs legacy pointer emulation via BTN_TOUCH, ABS_X, ABS_Y and
* ABS_PRESSURE. Touchpad finger count is emulated if use_count is true.
@@ -191,7 +192,8 @@ EXPORT_SYMBOL(input_mt_report_finger_count);
* The input core ensures only the KEY and ABS axes already setup for
* this device will produce output.
*/
-void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count)
+void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count,
+ bool hover)
{
struct input_mt *mt = dev->mt;
struct input_mt_slot *oldest;
@@ -220,6 +222,7 @@ void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count)
input_event(dev, EV_KEY, BTN_TOUCH, count > 0);
if (use_count)
input_mt_report_finger_count(dev, count);
+ input_event(dev, EV_ABS, ABS_DISTANCE, hover);
if (oldest) {
int x = input_mt_get_value(oldest, ABS_MT_POSITION_X);
@@ -290,7 +293,7 @@ void input_mt_sync_frame(struct input_dev *dev)
if ((mt->flags & INPUT_MT_POINTER) && !(mt->flags & INPUT_MT_SEMI_MT))
use_count = true;
- input_mt_report_pointer_emulation(dev, use_count);
+ input_mt_report_pointer_emulation(dev, use_count, false);
mt->frame++;
}
@@ -4,7 +4,7 @@
* Copyright (c) 2013 ELAN Microelectronics Corp.
*
* Author: ??? (Duson Lin) <dusonlin@emc.com.tw>
- * Version: 1.6.0
+ * Version: 1.6.2
*
* Based on cyapa driver:
* copyright (c) 2011-2012 Cypress Semiconductor, Inc.
@@ -40,7 +40,7 @@
#include "elan_i2c.h"
#define DRIVER_NAME "elan_i2c"
-#define ELAN_DRIVER_VERSION "1.6.1"
+#define ELAN_DRIVER_VERSION "1.6.2"
#define ELAN_VENDOR_ID 0x04f3
#define ETP_MAX_PRESSURE 255
#define ETP_FWIDTH_REDUCE 90
@@ -845,7 +845,7 @@ static void elan_report_absolute(struct elan_tp_data *data, u8 *packet)
{
struct input_dev *input = data->input;
u8 *finger_data = &packet[ETP_FINGER_DATA_OFFSET];
- int i;
+ int i, valid_count = 0;
u8 tp_info = packet[ETP_TOUCH_INFO_OFFSET];
u8 hover_info = packet[ETP_HOVER_INFO_OFFSET];
bool contact_valid, hover_event;
@@ -855,13 +855,16 @@ static void elan_report_absolute(struct elan_tp_data *data, u8 *packet)
contact_valid = tp_info & (1U << (3 + i));
elan_report_contact(data, i, contact_valid, finger_data);
- if (contact_valid)
+ if (contact_valid) {
finger_data += ETP_FINGER_DATA_LEN;
+ valid_count++;
+ }
}
input_report_key(input, BTN_LEFT, tp_info & 0x01);
- input_report_abs(input, ABS_DISTANCE, hover_event != 0);
- input_mt_report_pointer_emulation(input, true);
+ input_report_key(input, BTN_TOOL_FINGER,
+ ((hover_event != 0) || (valid_count > 0)));
+ input_mt_report_pointer_emulation(input, false, hover_event != 0);
input_sync(input);
}
@@ -558,7 +558,7 @@ static void elantech_input_sync_v4(struct psmouse *psmouse)
input_report_key(dev, BTN_MIDDLE, packet[0] & 0x04);
}
- input_mt_report_pointer_emulation(dev, true);
+ input_mt_report_pointer_emulation(dev, true, false);
input_sync(dev);
}
@@ -144,7 +144,7 @@ static void focaltech_report_state(struct psmouse *psmouse)
input_report_abs(dev, ABS_TOOL_WIDTH, state->width);
}
}
- input_mt_report_pointer_emulation(dev, true);
+ input_mt_report_pointer_emulation(dev, true, false);
input_report_key(psmouse->dev, BTN_LEFT, state->pressed);
input_sync(psmouse->dev);
@@ -944,7 +944,7 @@ static void synaptics_report_mt_data(struct psmouse *psmouse,
input_mt_drop_unused(dev);
/* Don't use active slot count to generate BTN_TOOL events. */
- input_mt_report_pointer_emulation(dev, false);
+ input_mt_report_pointer_emulation(dev, false, false);
/* Send the number of fingers reported by touchpad itself. */
input_mt_report_finger_count(dev, num_fingers);
@@ -683,7 +683,7 @@ static void mxt_input_button(struct mxt_data *data, u8 *message)
static void mxt_input_sync(struct mxt_data *data)
{
input_mt_report_pointer_emulation(data->input_dev,
- data->pdata->t19_num_keys);
+ data->pdata->t19_num_keys, false);
input_sync(data->input_dev);
}
@@ -250,7 +250,7 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
input_report_abs(tsdata->input, ABS_MT_POSITION_Y, y);
}
- input_mt_report_pointer_emulation(tsdata->input, true);
+ input_mt_report_pointer_emulation(tsdata->input, true, false);
input_sync(tsdata->input);
out:
@@ -113,7 +113,7 @@ static irqreturn_t egalax_ts_interrupt(int irq, void *dev_id)
input_report_abs(input_dev, ABS_MT_PRESSURE, z);
}
- input_mt_report_pointer_emulation(input_dev, true);
+ input_mt_report_pointer_emulation(input_dev, true, false);
input_sync(input_dev);
return IRQ_HANDLED;
@@ -99,7 +99,7 @@ static void ili210x_report_events(struct input_dev *input,
}
}
- input_mt_report_pointer_emulation(input, false);
+ input_mt_report_pointer_emulation(input, false, false);
input_sync(input);
}
@@ -221,7 +221,7 @@ static irqreturn_t mms114_interrupt(int irq, void *dev_id)
for (index = 0; index < touch_size; index++)
mms114_process_mt(data, touch + index);
- input_mt_report_pointer_emulation(data->input_dev, true);
+ input_mt_report_pointer_emulation(data->input_dev, true, false);
input_sync(data->input_dev);
out:
@@ -528,7 +528,7 @@ static int __maybe_unused mms114_suspend(struct device *dev)
input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, false);
}
- input_mt_report_pointer_emulation(input_dev, true);
+ input_mt_report_pointer_emulation(input_dev, true, false);
input_sync(input_dev);
mutex_lock(&input_dev->mutex);
@@ -81,7 +81,7 @@ static void pm_mtevent(struct pm *pm, struct input_dev *input)
}
}
- input_mt_report_pointer_emulation(input, true);
+ input_mt_report_pointer_emulation(input, true, false);
input_sync(input);
}
@@ -627,7 +627,7 @@ static irqreturn_t rohm_ts_soft_irq(int irq, void *dev_id)
}
input_mt_sync_frame(input_dev);
- input_mt_report_pointer_emulation(input_dev, true);
+ input_mt_report_pointer_emulation(input_dev, true, false);
input_sync(input_dev);
ts->finger_count = finger_count;
@@ -176,7 +176,7 @@ static void parse_multi_touch(struct w8001 *w8001)
if (w8001->type != BTN_TOOL_PEN &&
w8001->type != BTN_TOOL_RUBBER) {
w8001->type = count == 1 ? BTN_TOOL_FINGER : KEY_RESERVED;
- input_mt_report_pointer_emulation(dev, true);
+ input_mt_report_pointer_emulation(dev, true, false);
}
input_sync(dev);
@@ -104,7 +104,8 @@ void input_mt_report_slot_state(struct input_dev *dev,
unsigned int tool_type, bool active);
void input_mt_report_finger_count(struct input_dev *dev, int count);
-void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count);
+void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count,
+ bool hover);
void input_mt_drop_unused(struct input_dev *dev);
void input_mt_sync_frame(struct input_dev *dev);