Inter-revision diff: patch 10

Comparing v2 (message) to v1 (message)

--- v2
+++ v1
@@ -1,151 +1,65 @@
-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.
+Upload shared haptic affects for release and press waveforms if a device
+exposes them.
 
 Signed-off-by: Angela Czubak <acz@semihalf.com>
 ---
- drivers/hid/hid-haptic.c | 71 +++++++++++++++++++++++++++++++++++++++-
- drivers/hid/hid-haptic.h | 18 ++++++++++
- 2 files changed, 88 insertions(+), 1 deletion(-)
+ drivers/hid/hid-haptic.c | 34 ++++++++++++++++++++++++++++++++++
+ 1 file changed, 34 insertions(+)
 
 diff --git a/drivers/hid/hid-haptic.c b/drivers/hid/hid-haptic.c
-index 64e354cb3f2e..4a5d5e7b92d1 100644
+index b66bde7475e4..ad458bc7d4c5 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_check_pressure_unit(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);
- 		return true;
+@@ -367,6 +367,7 @@ int hid_haptic_init(struct hid_device *hdev,
+ 	char *name;
+ 	int (*flush)(struct input_dev *dev, struct file *file);
+ 	int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value);
++	struct ff_effect release_effect, press_effect;
+ 
+ 	haptic->hdev = hdev;
+ 	haptic->max_waveform_id = max(2u, haptic->max_waveform_id);
+@@ -483,8 +484,41 @@ int hid_haptic_init(struct hid_device *hdev,
+ 		module_put(THIS_MODULE);
+ 		goto input_free;
+ 	}
++
++	effect_set_default(&release_effect);
++	if (haptic->release_ordinal_orig)
++		release_effect.u.hid.hid_usage = HID_HP_WAVEFORMRELEASE &
++			HID_USAGE;
++	ret = input_ff_upload(dev, &release_effect, (struct file *)UINTPTR_MAX);
++	if (ret || release_effect.id != HID_HAPTIC_RELEASE_EFFECT_ID) {
++		if (!ret) {
++			ret = -EBUSY;
++			input_ff_erase(dev, release_effect.id,
++				       (struct file *)UINTPTR_MAX);
++		}
++		dev_err(&hdev->dev,
++			"Failed to allocate id 0 for release effect.\n");
++		goto input_free;
 +	}
- 	return false;
- }
- EXPORT_SYMBOL_GPL(hid_haptic_check_pressure_unit);
-@@ -350,6 +355,12 @@ static void hid_haptic_destroy(struct ff_device *ff)
- 	module_put(THIS_MODULE);
- }
++	effect_set_default(&press_effect);
++	if (haptic->press_ordinal_orig)
++		press_effect.u.hid.hid_usage = HID_HP_WAVEFORMPRESS & HID_USAGE;
++	ret = input_ff_upload(dev, &press_effect, (struct file *)UINTPTR_MAX);
++	if (ret || press_effect.id != HID_HAPTIC_PRESS_EFFECT_ID) {
++		if (!ret) {
++			ret = -EBUSY;
++			input_ff_erase(dev, press_effect.id,
++				       (struct file *)UINTPTR_MAX);
++		}
++		dev_err(&hdev->dev,
++			"Failed to allocate id 1 for press effect.\n");
++		goto release_free;
++	}
++
+ 	return 0;
  
-+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)
- {
-@@ -457,6 +468,13 @@ int hid_haptic_init(struct hid_device *hdev,
- 	fill_effect_buf(haptic, &stop_effect, &haptic->stop_effect,
- 			HID_HAPTIC_ORDINAL_WAVEFORMSTOP);
- 
-+	haptic->mode = HID_HAPTIC_MODE_DEVICE;
-+	haptic->press_threshold = convert_force_to_logical(haptic,
-+							   HID_HAPTIC_PRESS_THRESH);
-+	haptic->release_threshold = convert_force_to_logical(haptic,
-+							     HID_HAPTIC_RELEASE_THRESH);
-+
-+
- 	input_set_capability(dev, EV_FF, FF_HID);
- 
- 	flush = dev->flush;
-@@ -548,3 +566,54 @@ 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->pressure_sum > haptic->press_threshold)
-+		haptic->pressed_state = 1;
-+	else if (haptic->pressure_sum < 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->mode == HID_HAPTIC_MODE_KERNEL) {
-+		input_event(haptic->input_dev, EV_KEY, BTN_LEFT,
-+			    haptic->pressed_state);
-+		input_event(haptic->input_dev, EV_ABS, ABS_PRESSURE,
-+			    haptic->pressure_sum);
-+		return true;
-+	}
-+	return false;
-+}
-+EXPORT_SYMBOL_GPL(hid_haptic_handle_input);
-+
-+void hid_haptic_pressure_reset(struct hid_haptic_device *haptic)
-+{
-+	haptic->pressure_sum = 0;
-+}
-+EXPORT_SYMBOL_GPL(hid_haptic_pressure_reset);
-+
-+void hid_haptic_pressure_increase(struct hid_haptic_device *haptic,
-+				 __s32 pressure)
-+{
-+	haptic->pressure_sum += pressure;
-+}
-+EXPORT_SYMBOL_GPL(hid_haptic_pressure_increase);
-diff --git a/drivers/hid/hid-haptic.h b/drivers/hid/hid-haptic.h
-index e686f7ec42b9..586f20be0061 100644
---- a/drivers/hid/hid-haptic.h
-+++ b/drivers/hid/hid-haptic.h
-@@ -83,6 +83,11 @@ int hid_haptic_input_configured(struct hid_device *hdev,
- 				struct hid_haptic_device *haptic,
- 				struct hid_input *hi);
- 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_increase(struct hid_haptic_device *haptic,
-+				  __s32 pressure);
- #else
- static inline
- void hid_haptic_feature_mapping(struct hid_device *hdev,
-@@ -117,4 +122,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_increase(struct hid_haptic_device *haptic,
-+				  __s32 pressure)
-+{}
- #endif
++release_free:
++	input_ff_erase(dev, release_effect.id, (struct file *)UINTPTR_MAX);
+ input_free:
+ 	input_ff_destroy(dev);
+ 	/* Do not let double free happen, input_ff_destroy will call
 -- 
-2.34.1.703.g22d0c6ccf7-goog
+2.34.1.307.g9b7440fafd-goog
 
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help