@@ -226,6 +226,13 @@ static void switch_mode(struct hid_device *hdev, struct hid_haptic_device *hapti
haptic->mode = mode;
}
+void hid_haptic_reset(struct hid_device *hdev, struct hid_haptic_device *haptic)
+{
+ if (haptic->press_ordinal_cur && haptic->release_ordinal_cur)
+ switch_mode(hdev, haptic, HID_HAPTIC_MODE_KERNEL);
+}
+EXPORT_SYMBOL_GPL(hid_haptic_reset);
+
#ifdef CONFIG_PM
void hid_haptic_resume(struct hid_device *hdev, struct hid_haptic_device *haptic)
{
@@ -82,6 +82,7 @@ int hid_haptic_input_mapping(struct hid_device *hdev,
unsigned long **bit, int *max);
bool hid_haptic_input_configured(struct hid_device *hdev,
struct hid_haptic_device *haptic);
+void hid_haptic_reset(struct hid_device *hdev, struct hid_haptic_device *haptic);
#ifdef CONFIG_PM
void hid_haptic_resume(struct hid_device *hdev, struct hid_haptic_device *haptic);
void hid_haptic_suspend(struct hid_device *hdev, struct hid_haptic_device *haptic);
@@ -120,6 +121,10 @@ bool hid_haptic_input_configured(struct hid_device *hdev,
{
return 0;
}
+static inline
+void hid_haptic_reset(struct hid_device *hdev, struct hid_haptic_device *haptic)
+{
+}
#ifdef CONFIG_PM
static inline
void hid_haptic_resume(struct hid_device *hdev, struct hid_haptic_device *haptic) {}
@@ -1877,6 +1877,20 @@ static int mt_resume(struct hid_device *hdev)
}
#endif
+static int mt_reset(struct hid_device *hdev)
+{
+ struct mt_device *td = hid_get_drvdata(hdev);
+ struct hid_haptic_device *haptic = td->haptic;
+
+ mt_release_contacts(hdev);
+ mt_set_modes(hdev, HID_LATENCY_NORMAL, true, true);
+
+ if (td->is_haptic_touchpad)
+ hid_haptic_reset(hdev, haptic);
+
+ return 0;
+}
+
static void mt_remove(struct hid_device *hdev)
{
struct mt_device *td = hid_get_drvdata(hdev);
@@ -2284,6 +2298,7 @@ static struct hid_driver mt_driver = {
#ifdef CONFIG_PM
.suspend = mt_suspend,
.reset_resume = mt_reset_resume,
+ .reset = mt_reset,
.resume = mt_resume,
#endif
};
When a haptic device performs device initiated reset it puts itself back into autonomous mode. This leads to incosistency in the actual device state and the state configured by the kernel (manual mode). Hence user may observe duplicated force feedback, initiated by the device itself (due to its autonomous mode) and the host (by sending manual reports). Configure the device and put it back into manual mode once reset is noticed. Signed-off-by: Angela Czubak <acz@semihalf.com> --- drivers/hid/hid-haptic.c | 7 +++++++ drivers/hid/hid-haptic.h | 5 +++++ drivers/hid/hid-multitouch.c | 15 +++++++++++++++ 3 files changed, 27 insertions(+)