All of lore.kernel.org
 help / color / mirror / Atom feed
From: Angela Czubak <acz@semihalf.com>
To: linux-input@vger.kernel.org
Cc: upstream@semihalf.com, benjamin.tissoires@redhat.com,
	jikos@kernel.org, dmitry.torokhov@gmail.com,
	Angela Czubak <acz@semihalf.com>
Subject: [PATCH v3 09/17] HID: haptic: add functions handling events
Date: Fri, 13 May 2022 09:39:19 +0000	[thread overview]
Message-ID: <20220513093927.1632262-10-acz@semihalf.com> (raw)
In-Reply-To: <20220513093927.1632262-1-acz@semihalf.com>

Implement hid_haptic_handle_press_release() which generates haptic feedback
as well as saves the pressed state of the haptic device.
Function hid_haptic_handle_input() inserts BTN_LEFT and ABS_PRESSURE events
if the device is in kernel mode.
Add functions to increase and reset the state of the pressure detected by
the device.

Signed-off-by: Angela Czubak <acz@semihalf.com>
---
 drivers/hid/hid-haptic.c | 73 +++++++++++++++++++++++++++++++++++++++-
 drivers/hid/hid-haptic.h | 18 ++++++++++
 2 files changed, 90 insertions(+), 1 deletion(-)

diff --git a/drivers/hid/hid-haptic.c b/drivers/hid/hid-haptic.c
index 3301bf27dfde..9b89a1f8a631 100644
--- a/drivers/hid/hid-haptic.c
+++ b/drivers/hid/hid-haptic.c
@@ -50,8 +50,13 @@ EXPORT_SYMBOL_GPL(hid_haptic_feature_mapping);
 bool hid_haptic_is_forcepad(struct hid_haptic_device *haptic,
 			    struct hid_input *hi, struct hid_field *field)
 {
-	if (field->unit == HID_UNIT_GRAM || field->unit == HID_UNIT_NEWTON)
+	if (field->unit == HID_UNIT_GRAM || field->unit == HID_UNIT_NEWTON) {
+		haptic->force_logical_minimum = field->logical_minimum;
+		haptic->force_physical_minimum = field->physical_minimum;
+		haptic->force_resolution = input_abs_get_res(hi->input,
+							     ABS_MT_PRESSURE);
 		haptic->is_forcepad = true;
+	}
 	return haptic->is_forcepad;
 }
 EXPORT_SYMBOL_GPL(hid_haptic_is_forcepad);
@@ -346,6 +351,12 @@ static void hid_haptic_destroy(struct ff_device *ff)
 	module_put(THIS_MODULE);
 }
 
+static u32 convert_force_to_logical(struct hid_haptic_device *haptic, u32 value)
+{
+	return (value - haptic->force_physical_minimum) *
+		haptic->force_resolution + haptic->force_logical_minimum;
+}
+
 int hid_haptic_init(struct hid_device *hdev,
 		    struct hid_haptic_device **haptic_ptr)
 {
@@ -479,9 +490,16 @@ int hid_haptic_init(struct hid_device *hdev,
 		goto input_free;
 	}
 
+	haptic->mode = HID_HAPTIC_MODE_DEVICE;
+
 	if (!haptic->is_forcepad)
 		goto exit;
 
+	haptic->press_threshold = convert_force_to_logical(haptic,
+							   HID_HAPTIC_PRESS_THRESH);
+	haptic->release_threshold = convert_force_to_logical(haptic,
+							     HID_HAPTIC_RELEASE_THRESH);
+
 	effect_set_default(&release_effect);
 	if (haptic->release_ordinal_orig)
 		release_effect.u.hid.hid_usage = HID_HP_WAVEFORMRELEASE &
@@ -547,3 +565,56 @@ int hid_haptic_init(struct hid_device *hdev,
 	return ret;
 }
 EXPORT_SYMBOL_GPL(hid_haptic_init);
+
+void hid_haptic_handle_press_release(struct hid_haptic_device *haptic)
+{
+	int prev_pressed_state = haptic->pressed_state;
+	struct input_dev *input = haptic->input_dev;
+	unsigned long flags;
+
+	if (!haptic->is_forcepad)
+		return;
+
+	if (haptic->pressure > haptic->press_threshold)
+		haptic->pressed_state = 1;
+	else if (haptic->pressure < haptic->release_threshold)
+		haptic->pressed_state = 0;
+	if (!prev_pressed_state && haptic->pressed_state &&
+	    haptic->mode == HID_HAPTIC_MODE_KERNEL) {
+		spin_lock_irqsave(&input->event_lock, flags);
+		input->ff->playback(input, PRESS_HID_EFFECT_ID, 1);
+		spin_unlock_irqrestore(&input->event_lock, flags);
+	}
+	if (prev_pressed_state && !haptic->pressed_state &&
+	    haptic->mode == HID_HAPTIC_MODE_KERNEL) {
+		spin_lock_irqsave(&input->event_lock, flags);
+		input->ff->playback(input, RELEASE_HID_EFFECT_ID, 1);
+		spin_unlock_irqrestore(&input->event_lock, flags);
+	}
+}
+EXPORT_SYMBOL_GPL(hid_haptic_handle_press_release);
+
+bool hid_haptic_handle_input(struct hid_haptic_device *haptic)
+{
+	if (haptic->is_forcepad && haptic->mode == HID_HAPTIC_MODE_KERNEL) {
+		input_event(haptic->input_dev, EV_KEY, BTN_LEFT,
+			    haptic->pressed_state);
+		return true;
+	}
+	return false;
+}
+EXPORT_SYMBOL_GPL(hid_haptic_handle_input);
+
+void hid_haptic_pressure_reset(struct hid_haptic_device *haptic)
+{
+	haptic->pressure = 0;
+}
+EXPORT_SYMBOL_GPL(hid_haptic_pressure_reset);
+
+void hid_haptic_pressure_update(struct hid_haptic_device *haptic,
+				__s32 pressure)
+{
+	if (pressure > haptic->pressure)
+		haptic->pressure = pressure;
+}
+EXPORT_SYMBOL_GPL(hid_haptic_pressure_update);
diff --git a/drivers/hid/hid-haptic.h b/drivers/hid/hid-haptic.h
index 67096cc8c233..c26093e3773d 100644
--- a/drivers/hid/hid-haptic.h
+++ b/drivers/hid/hid-haptic.h
@@ -83,6 +83,11 @@ int hid_haptic_input_mapping(struct hid_device *hdev,
 bool hid_haptic_input_configured(struct hid_device *hdev,
 				 struct hid_haptic_device *haptic);
 int hid_haptic_init(struct hid_device *hdev, struct hid_haptic_device **haptic_ptr);
+void hid_haptic_handle_press_release(struct hid_haptic_device *haptic);
+bool hid_haptic_handle_input(struct hid_haptic_device *haptic);
+void hid_haptic_pressure_reset(struct hid_haptic_device *haptic);
+void hid_haptic_pressure_update(struct hid_haptic_device *haptic,
+				__s32 pressure);
 #else
 static inline
 void hid_haptic_feature_mapping(struct hid_device *hdev,
@@ -116,4 +121,17 @@ int hid_haptic_init(struct hid_device *hdev, struct hid_haptic_device **haptic_p
 {
 	return 0;
 }
+static inline
+void hid_haptic_handle_press_release(struct hid_haptic_device *haptic) {}
+static inline
+bool hid_haptic_handle_input(struct hid_haptic_device *haptic)
+{
+	return false;
+}
+static inline
+void hid_haptic_pressure_reset(struct hid_haptic_device *haptic) {}
+static inline
+void hid_haptic_pressure_update(struct hid_haptic_device *haptic,
+				  __s32 pressure)
+{}
 #endif
-- 
2.36.0.550.gb090851708-goog


  parent reply	other threads:[~2022-05-13  9:40 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-13  9:39 [PATCH v3 00/17] *** Implement simple haptic HID support *** Angela Czubak
2022-05-13  9:39 ` [PATCH v3 01/17] HID: add haptics page defines Angela Czubak
2022-05-13  9:39 ` [PATCH v3 02/17] Input: add FF_HID effect type Angela Czubak
2022-05-13  9:39 ` [PATCH v3 03/17] HID: haptic: introduce hid_haptic_device Angela Czubak
2022-05-13  9:39 ` [PATCH v3 04/17] HID: input: allow mapping of haptic output Angela Czubak
2022-05-13  9:39 ` [PATCH v3 05/17] HID: haptic: initialize haptic device Angela Czubak
2022-05-13  9:39 ` [PATCH v3 06/17] Input: add shared effects Angela Czubak
2022-05-13  9:39 ` [PATCH v3 07/17] HID: haptic: implement release and press effects Angela Czubak
2022-05-13  9:39 ` [PATCH v3 08/17] HID: input: calculate resolution for pressure Angela Czubak
2022-05-13  9:39 ` Angela Czubak [this message]
2022-05-13  9:39 ` [PATCH v3 10/17] Input: MT - add INPUT_MT_MAX_FORCE flags Angela Czubak
2022-05-13  9:39 ` [PATCH v3 11/17] HID: haptic: add hid_haptic_switch_mode Angela Czubak
2022-05-13  9:39 ` [PATCH v3 12/17] HID: multitouch: add haptic multitouch support Angela Czubak
2022-05-13  9:39 ` [PATCH v3 13/17] Input: introduce EVIOCFF(TAKE|RELEASE)CONTROL Angela Czubak
2022-05-13  9:39 ` [PATCH v3 14/17] HID: haptic: add hid_haptic_change_control Angela Czubak
2022-05-13  9:39 ` [PATCH v3 15/17] HID: add HID device reset callback Angela Czubak
2022-05-13  9:39 ` [PATCH v3 16/17] HID: haptic: implement HID haptic " Angela Czubak
2022-05-13  9:39 ` [PATCH v3 17/17] HID: multitouch: Add lid handler for touchpad on Redrix chromebook Angela Czubak
2022-05-15  0:07   ` marcoshalano
2022-05-22 17:55 ` [PATCH v3 00/17] *** Implement simple haptic HID support *** Angela Czubak
2022-05-23  6:57   ` Jiri Kosina

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220513093927.1632262-10-acz@semihalf.com \
    --to=acz@semihalf.com \
    --cc=benjamin.tissoires@redhat.com \
    --cc=dmitry.torokhov@gmail.com \
    --cc=jikos@kernel.org \
    --cc=linux-input@vger.kernel.org \
    --cc=upstream@semihalf.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.