* [PATCH 1/3] HID: rmi: Support non rmi devices by passing events to hid-input
@ 2014-12-19 22:45 Andrew Duggan
2014-12-19 22:45 ` [PATCH 2/3] HID: rmi: Support touchpads with external buttons Andrew Duggan
` (3 more replies)
0 siblings, 4 replies; 7+ messages in thread
From: Andrew Duggan @ 2014-12-19 22:45 UTC (permalink / raw)
To: linux-input, linux-kernel; +Cc: Andrew Duggan, Jiri Kosina, Benjamin Tissoires
Allowing hid-rmi to bind to non rmi devices allows us to support composite USB
devices which contain several HID devices one of which is a HID touchpad.
Since all of the devices have the same VID and PID we can add the device
to the hid_have_special_driver list and have hid-rmi handle all of the devices.
Then hid-rmi's probe can look for the rmi specific HID report IDs and decide if
it should handle the device as a rmi device or simply report that the events
needs additional processing.
Signed-off-by: Andrew Duggan <aduggan@synaptics.com>
---
This patch series is my second attempt at getting the hid-rmi driver working on
the Razer Blade 14 based on Benjamin's comments. I decided to break it up into
three separate patches. This one allows hid-rmi to bind to all of the devices.
Instead of adding a quirk I just look at the report IDs to see if it should
do rmi or not.
drivers/hid/hid-rmi.c | 93 +++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 76 insertions(+), 17 deletions(-)
diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c
index b51200f..018f80f 100644
--- a/drivers/hid/hid-rmi.c
+++ b/drivers/hid/hid-rmi.c
@@ -33,6 +33,9 @@
#define RMI_READ_DATA_PENDING BIT(1)
#define RMI_STARTED BIT(2)
+/* device flags */
+#define RMI_DEVICE BIT(0)
+
enum rmi_mode_type {
RMI_MODE_OFF = 0,
RMI_MODE_ATTN_REPORTS = 1,
@@ -118,6 +121,8 @@ struct rmi_data {
struct work_struct reset_work;
struct hid_device *hdev;
+
+ unsigned long device_flags;
};
#define RMI_PAGE(addr) (((addr) >> 8) & 0xff)
@@ -452,9 +457,23 @@ static int rmi_raw_event(struct hid_device *hdev,
return rmi_read_data_event(hdev, data, size);
case RMI_ATTN_REPORT_ID:
return rmi_input_event(hdev, data, size);
- case RMI_MOUSE_REPORT_ID:
+ default:
+ return 1;
+ }
+
+ return 0;
+}
+
+static int rmi_event(struct hid_device *hdev, struct hid_field *field,
+ struct hid_usage *usage, __s32 value)
+{
+ struct rmi_data *data = hid_get_drvdata(hdev);
+
+ if ((data->device_flags & RMI_DEVICE) &&
+ (field->application == HID_GD_POINTER ||
+ field->application == HID_GD_MOUSE)) {
rmi_schedule_reset(hdev);
- break;
+ return 1;
}
return 0;
@@ -856,6 +875,9 @@ static void rmi_input_configured(struct hid_device *hdev, struct hid_input *hi)
if (ret)
return;
+ if (!(data->device_flags & RMI_DEVICE))
+ return;
+
/* Allow incoming hid reports */
hid_device_io_start(hdev);
@@ -914,8 +936,33 @@ static int rmi_input_mapping(struct hid_device *hdev,
struct hid_input *hi, struct hid_field *field,
struct hid_usage *usage, unsigned long **bit, int *max)
{
- /* we want to make HID ignore the advertised HID collection */
- return -1;
+ struct rmi_data *data = hid_get_drvdata(hdev);
+
+ /*
+ * we want to make HID ignore the advertised HID collection
+ * for RMI deivces
+ */
+ if (data->device_flags & RMI_DEVICE)
+ return -1;
+
+ return 0;
+}
+
+static int rmi_check_valid_report_id(struct hid_device *hdev, unsigned type,
+ unsigned id, struct hid_report **report)
+{
+ int i;
+
+ *report = hdev->report_enum[type].report_id_hash[id];
+ if (*report) {
+ for (i = 0; i < (*report)->maxfield; i++) {
+ unsigned app = (*report)->field[i]->application;
+ if ((app & HID_USAGE_PAGE) >= HID_UP_MSVENDOR)
+ return 1;
+ }
+ }
+
+ return 0;
}
static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id)
@@ -925,6 +972,7 @@ static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id)
size_t alloc_size;
struct hid_report *input_report;
struct hid_report *output_report;
+ struct hid_report *feature_report;
data = devm_kzalloc(&hdev->dev, sizeof(struct rmi_data), GFP_KERNEL);
if (!data)
@@ -943,27 +991,35 @@ static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id)
return ret;
}
- input_report = hdev->report_enum[HID_INPUT_REPORT]
- .report_id_hash[RMI_ATTN_REPORT_ID];
- if (!input_report) {
- hid_err(hdev, "device does not have expected input report\n");
- ret = -ENODEV;
- return ret;
+ /*
+ * Check for the RMI specific report ids. If they are misisng
+ * simply return and let the events be processed by hid-input
+ */
+ if (!rmi_check_valid_report_id(hdev, HID_FEATURE_REPORT,
+ RMI_SET_RMI_MODE_REPORT_ID, &feature_report)) {
+ hid_dbg(hdev, "device does not have set mode feature report\n");
+ goto start;
+ }
+
+ if (!rmi_check_valid_report_id(hdev, HID_INPUT_REPORT,
+ RMI_ATTN_REPORT_ID, &input_report)) {
+ hid_dbg(hdev, "device does not have attention input report\n");
+ goto start;
}
data->input_report_size = (input_report->size >> 3) + 1 /* report id */;
- output_report = hdev->report_enum[HID_OUTPUT_REPORT]
- .report_id_hash[RMI_WRITE_REPORT_ID];
- if (!output_report) {
- hid_err(hdev, "device does not have expected output report\n");
- ret = -ENODEV;
- return ret;
+ if (!rmi_check_valid_report_id(hdev, HID_OUTPUT_REPORT,
+ RMI_WRITE_REPORT_ID, &output_report)) {
+ hid_dbg(hdev,
+ "device does not have rmi write output report\n");
+ goto start;
}
data->output_report_size = (output_report->size >> 3)
+ 1 /* report id */;
+ data->device_flags |= RMI_DEVICE;
alloc_size = data->output_report_size + data->input_report_size;
data->writeReport = devm_kzalloc(&hdev->dev, alloc_size, GFP_KERNEL);
@@ -978,13 +1034,15 @@ static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id)
mutex_init(&data->page_mutex);
+start:
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
if (ret) {
hid_err(hdev, "hw start failed\n");
return ret;
}
- if (!test_bit(RMI_STARTED, &data->flags))
+ if ((data->device_flags & RMI_DEVICE) &&
+ !test_bit(RMI_STARTED, &data->flags))
/*
* The device maybe in the bootloader if rmi_input_configured
* failed to find F11 in the PDT. Print an error, but don't
@@ -1017,6 +1075,7 @@ static struct hid_driver rmi_driver = {
.id_table = rmi_id,
.probe = rmi_probe,
.remove = rmi_remove,
+ .event = rmi_event,
.raw_event = rmi_raw_event,
.input_mapping = rmi_input_mapping,
.input_configured = rmi_input_configured,
--
2.1.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/3] HID: rmi: Support touchpads with external buttons
2014-12-19 22:45 [PATCH 1/3] HID: rmi: Support non rmi devices by passing events to hid-input Andrew Duggan
@ 2014-12-19 22:45 ` Andrew Duggan
2014-12-20 1:53 ` Benjamin Tissoires
2014-12-19 22:45 ` [PATCH 3/3] HID: rmi: Add support for the touchpad in the Razer Blade 14 laptop Andrew Duggan
` (2 subsequent siblings)
3 siblings, 1 reply; 7+ messages in thread
From: Andrew Duggan @ 2014-12-19 22:45 UTC (permalink / raw)
To: linux-input, linux-kernel; +Cc: Andrew Duggan, Jiri Kosina, Benjamin Tissoires
The external buttons on HID touchpads are connected as pass through devices and
button events are not reported in the rmi registers. As a result on these
devices we need to allow the HID generic desktop button events to be processed
by hid-input.
Signed-off-by: Andrew Duggan <aduggan@synaptics.com>
---
drivers/hid/hid-rmi.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c
index 018f80f..cdfe165 100644
--- a/drivers/hid/hid-rmi.c
+++ b/drivers/hid/hid-rmi.c
@@ -35,6 +35,7 @@
/* device flags */
#define RMI_DEVICE BIT(0)
+#define RMI_DEVICE_HAS_PHYS_BUTTONS BIT(1)
enum rmi_mode_type {
RMI_MODE_OFF = 0,
@@ -472,6 +473,9 @@ static int rmi_event(struct hid_device *hdev, struct hid_field *field,
if ((data->device_flags & RMI_DEVICE) &&
(field->application == HID_GD_POINTER ||
field->application == HID_GD_MOUSE)) {
+ if ((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON)
+ return 0;
+
rmi_schedule_reset(hdev);
return 1;
}
@@ -942,6 +946,10 @@ static int rmi_input_mapping(struct hid_device *hdev,
* we want to make HID ignore the advertised HID collection
* for RMI deivces
*/
+ if ((data->device_flags & RMI_DEVICE_HAS_PHYS_BUTTONS) &&
+ ((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON))
+ return 0;
+
if (data->device_flags & RMI_DEVICE)
return -1;
--
2.1.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 2/3] HID: rmi: Support touchpads with external buttons
2014-12-19 22:45 ` [PATCH 2/3] HID: rmi: Support touchpads with external buttons Andrew Duggan
@ 2014-12-20 1:53 ` Benjamin Tissoires
0 siblings, 0 replies; 7+ messages in thread
From: Benjamin Tissoires @ 2014-12-20 1:53 UTC (permalink / raw)
To: Andrew Duggan; +Cc: linux-input, linux-kernel, Jiri Kosina
On Dec 19 2014 or thereabouts, Andrew Duggan wrote:
> The external buttons on HID touchpads are connected as pass through devices and
> button events are not reported in the rmi registers. As a result on these
> devices we need to allow the HID generic desktop button events to be processed
> by hid-input.
>
> Signed-off-by: Andrew Duggan <aduggan@synaptics.com>
> ---
Just to be sure, could you also add in the commit message that the flag
RMI_DEVICE_HAS_PHYS_BUTTONS is not auto-detected by the driver and that
it has to be added manually when adding a device to rmi_id[].
BTW, you can use .driver_data in in struct hid_device_id to pass the
flags directly. So here, it would be nice to add such retrieval in
probe:
data->device_flags = id->driver_data;
and then check for RMI_DEVICE.
> drivers/hid/hid-rmi.c | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c
> index 018f80f..cdfe165 100644
> --- a/drivers/hid/hid-rmi.c
> +++ b/drivers/hid/hid-rmi.c
> @@ -35,6 +35,7 @@
>
> /* device flags */
> #define RMI_DEVICE BIT(0)
> +#define RMI_DEVICE_HAS_PHYS_BUTTONS BIT(1)
>
> enum rmi_mode_type {
> RMI_MODE_OFF = 0,
> @@ -472,6 +473,9 @@ static int rmi_event(struct hid_device *hdev, struct hid_field *field,
> if ((data->device_flags & RMI_DEVICE) &&
> (field->application == HID_GD_POINTER ||
> field->application == HID_GD_MOUSE)) {
> + if ((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON)
> + return 0;
> +
> rmi_schedule_reset(hdev);
I think here you will get a reset for each button press. I believe the
mouse collection is pretty generic and you should also get the relX|Y
events with the button press.
> return 1;
> }
> @@ -942,6 +946,10 @@ static int rmi_input_mapping(struct hid_device *hdev,
> * we want to make HID ignore the advertised HID collection
> * for RMI deivces
> */
> + if ((data->device_flags & RMI_DEVICE_HAS_PHYS_BUTTONS) &&
> + ((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON))
> + return 0;
> +
> if (data->device_flags & RMI_DEVICE)
> return -1;
>
> --
> 2.1.0
>
Cheers,
Benjamin
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 3/3] HID: rmi: Add support for the touchpad in the Razer Blade 14 laptop
2014-12-19 22:45 [PATCH 1/3] HID: rmi: Support non rmi devices by passing events to hid-input Andrew Duggan
2014-12-19 22:45 ` [PATCH 2/3] HID: rmi: Support touchpads with external buttons Andrew Duggan
@ 2014-12-19 22:45 ` Andrew Duggan
2014-12-20 1:56 ` Benjamin Tissoires
2014-12-20 1:42 ` [PATCH 1/3] HID: rmi: Support non rmi devices by passing events to hid-input Benjamin Tissoires
2014-12-22 13:24 ` Jiri Kosina
3 siblings, 1 reply; 7+ messages in thread
From: Andrew Duggan @ 2014-12-19 22:45 UTC (permalink / raw)
To: linux-input, linux-kernel; +Cc: Andrew Duggan, Jiri Kosina, Benjamin Tissoires
Have hid-rmi handle all of the Razer Blade HID devices that are part of the
composite USB device. This will allow hid-rmi to operate the touchpad in rmi
mode while passing events from the other devices to hid-input.
Signed-off-by: Andrew Duggan <aduggan@synaptics.com>
---
drivers/hid/hid-core.c | 1 +
drivers/hid/hid-ids.h | 3 +++
drivers/hid/hid-rmi.c | 15 +++++++++++++++
3 files changed, 19 insertions(+)
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 81665b4..ef718f9 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1982,6 +1982,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE2) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_RAZER, USB_DEVICE_ID_RAZER_BLADE_14) },
{ }
};
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 7460f34..7d0912d 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -767,6 +767,9 @@
#define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001 0x3001
#define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008 0x3008
+#define USB_VENDOR_ID_RAZER 0x1532
+#define USB_DEVICE_ID_RAZER_BLADE_14 0x011D
+
#define USB_VENDOR_ID_REALTEK 0x0bda
#define USB_DEVICE_ID_REALTEK_READER 0x0152
diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c
index cdfe165..849b35a 100644
--- a/drivers/hid/hid-rmi.c
+++ b/drivers/hid/hid-rmi.c
@@ -1038,6 +1038,20 @@ static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id)
data->readReport = data->writeReport + data->output_report_size;
+ /*
+ * Unfortunately there is no way to query the touchpad in the
+ * Razer system to determine that it has pass through buttons
+ * so the only solution is to set phys buttons flag based on the
+ * vid and pid. In the future we should be able to query devices
+ * to find out. However, we need to know if the touchpad has
+ * physical buttons before the input_mapping gets called which
+ * is before we query the device. So we may have to resort to creating
+ * a list of devices based on product id.
+ */
+ if (hdev->vendor == USB_VENDOR_ID_RAZER &&
+ hdev->product == USB_DEVICE_ID_RAZER_BLADE_14)
+ data->device_flags |= RMI_DEVICE_HAS_PHYS_BUTTONS;
+
init_waitqueue_head(&data->wait);
mutex_init(&data->page_mutex);
@@ -1074,6 +1088,7 @@ static void rmi_remove(struct hid_device *hdev)
static const struct hid_device_id rmi_id[] = {
{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_RMI, HID_ANY_ID, HID_ANY_ID) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_RAZER, USB_DEVICE_ID_RAZER_BLADE_14) },
{ }
};
MODULE_DEVICE_TABLE(hid, rmi_id);
--
2.1.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 3/3] HID: rmi: Add support for the touchpad in the Razer Blade 14 laptop
2014-12-19 22:45 ` [PATCH 3/3] HID: rmi: Add support for the touchpad in the Razer Blade 14 laptop Andrew Duggan
@ 2014-12-20 1:56 ` Benjamin Tissoires
0 siblings, 0 replies; 7+ messages in thread
From: Benjamin Tissoires @ 2014-12-20 1:56 UTC (permalink / raw)
To: Andrew Duggan; +Cc: linux-input, linux-kernel, Jiri Kosina
On Dec 19 2014 or thereabouts, Andrew Duggan wrote:
> Have hid-rmi handle all of the Razer Blade HID devices that are part of the
> composite USB device. This will allow hid-rmi to operate the touchpad in rmi
> mode while passing events from the other devices to hid-input.
>
> Signed-off-by: Andrew Duggan <aduggan@synaptics.com>
> ---
> drivers/hid/hid-core.c | 1 +
> drivers/hid/hid-ids.h | 3 +++
> drivers/hid/hid-rmi.c | 15 +++++++++++++++
> 3 files changed, 19 insertions(+)
>
> diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
> index 81665b4..ef718f9 100644
> --- a/drivers/hid/hid-core.c
> +++ b/drivers/hid/hid-core.c
> @@ -1982,6 +1982,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
> { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) },
> { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE) },
> { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE2) },
> + { HID_USB_DEVICE(USB_VENDOR_ID_RAZER, USB_DEVICE_ID_RAZER_BLADE_14) },
> { }
> };
>
> diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
> index 7460f34..7d0912d 100644
> --- a/drivers/hid/hid-ids.h
> +++ b/drivers/hid/hid-ids.h
> @@ -767,6 +767,9 @@
> #define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001 0x3001
> #define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008 0x3008
>
> +#define USB_VENDOR_ID_RAZER 0x1532
> +#define USB_DEVICE_ID_RAZER_BLADE_14 0x011D
> +
> #define USB_VENDOR_ID_REALTEK 0x0bda
> #define USB_DEVICE_ID_REALTEK_READER 0x0152
>
> diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c
> index cdfe165..849b35a 100644
> --- a/drivers/hid/hid-rmi.c
> +++ b/drivers/hid/hid-rmi.c
> @@ -1038,6 +1038,20 @@ static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id)
>
> data->readReport = data->writeReport + data->output_report_size;
>
> + /*
> + * Unfortunately there is no way to query the touchpad in the
> + * Razer system to determine that it has pass through buttons
> + * so the only solution is to set phys buttons flag based on the
> + * vid and pid. In the future we should be able to query devices
> + * to find out. However, we need to know if the touchpad has
> + * physical buttons before the input_mapping gets called which
> + * is before we query the device. So we may have to resort to creating
> + * a list of devices based on product id.
> + */
> + if (hdev->vendor == USB_VENDOR_ID_RAZER &&
> + hdev->product == USB_DEVICE_ID_RAZER_BLADE_14)
> + data->device_flags |= RMI_DEVICE_HAS_PHYS_BUTTONS;
This whole test can be replace by a field in rmi_id (.driver_data) as
mentioned in 2/3.
> +
> init_waitqueue_head(&data->wait);
>
> mutex_init(&data->page_mutex);
> @@ -1074,6 +1088,7 @@ static void rmi_remove(struct hid_device *hdev)
>
> static const struct hid_device_id rmi_id[] = {
> { HID_DEVICE(HID_BUS_ANY, HID_GROUP_RMI, HID_ANY_ID, HID_ANY_ID) },
> + { HID_USB_DEVICE(USB_VENDOR_ID_RAZER, USB_DEVICE_ID_RAZER_BLADE_14) },
Nitpicking, I'd prefer having the most generic one at the end. In case
you need to specify other flags to some specific devices, they will have
to be inserted before the catchall rule, so let's start now :).
> { }
> };
> MODULE_DEVICE_TABLE(hid, rmi_id);
> --
> 2.1.0
>
Cheers,
Benjamin
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/3] HID: rmi: Support non rmi devices by passing events to hid-input
2014-12-19 22:45 [PATCH 1/3] HID: rmi: Support non rmi devices by passing events to hid-input Andrew Duggan
2014-12-19 22:45 ` [PATCH 2/3] HID: rmi: Support touchpads with external buttons Andrew Duggan
2014-12-19 22:45 ` [PATCH 3/3] HID: rmi: Add support for the touchpad in the Razer Blade 14 laptop Andrew Duggan
@ 2014-12-20 1:42 ` Benjamin Tissoires
2014-12-22 13:24 ` Jiri Kosina
3 siblings, 0 replies; 7+ messages in thread
From: Benjamin Tissoires @ 2014-12-20 1:42 UTC (permalink / raw)
To: Andrew Duggan; +Cc: linux-input, linux-kernel, Jiri Kosina
On Dec 19 2014 or thereabouts, Andrew Duggan wrote:
> Allowing hid-rmi to bind to non rmi devices allows us to support composite USB
> devices which contain several HID devices one of which is a HID touchpad.
> Since all of the devices have the same VID and PID we can add the device
> to the hid_have_special_driver list and have hid-rmi handle all of the devices.
> Then hid-rmi's probe can look for the rmi specific HID report IDs and decide if
> it should handle the device as a rmi device or simply report that the events
> needs additional processing.
>
> Signed-off-by: Andrew Duggan <aduggan@synaptics.com>
> ---
> This patch series is my second attempt at getting the hid-rmi driver working on
> the Razer Blade 14 based on Benjamin's comments. I decided to break it up into
> three separate patches. This one allows hid-rmi to bind to all of the devices.
> Instead of adding a quirk I just look at the report IDs to see if it should
> do rmi or not.
Hi Andrew,
That's a good job on this series. I like it better than the previous one.
I have a concern in 2/3 and a nitpick in 3/3.
But this one (1/3) is
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
>
> drivers/hid/hid-rmi.c | 93 +++++++++++++++++++++++++++++++++++++++++----------
> 1 file changed, 76 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c
> index b51200f..018f80f 100644
> --- a/drivers/hid/hid-rmi.c
> +++ b/drivers/hid/hid-rmi.c
> @@ -33,6 +33,9 @@
> #define RMI_READ_DATA_PENDING BIT(1)
> #define RMI_STARTED BIT(2)
>
> +/* device flags */
> +#define RMI_DEVICE BIT(0)
> +
> enum rmi_mode_type {
> RMI_MODE_OFF = 0,
> RMI_MODE_ATTN_REPORTS = 1,
> @@ -118,6 +121,8 @@ struct rmi_data {
>
> struct work_struct reset_work;
> struct hid_device *hdev;
> +
> + unsigned long device_flags;
> };
>
> #define RMI_PAGE(addr) (((addr) >> 8) & 0xff)
> @@ -452,9 +457,23 @@ static int rmi_raw_event(struct hid_device *hdev,
> return rmi_read_data_event(hdev, data, size);
> case RMI_ATTN_REPORT_ID:
> return rmi_input_event(hdev, data, size);
> - case RMI_MOUSE_REPORT_ID:
> + default:
> + return 1;
> + }
> +
> + return 0;
> +}
> +
> +static int rmi_event(struct hid_device *hdev, struct hid_field *field,
> + struct hid_usage *usage, __s32 value)
> +{
> + struct rmi_data *data = hid_get_drvdata(hdev);
> +
> + if ((data->device_flags & RMI_DEVICE) &&
> + (field->application == HID_GD_POINTER ||
> + field->application == HID_GD_MOUSE)) {
> rmi_schedule_reset(hdev);
> - break;
> + return 1;
> }
>
> return 0;
> @@ -856,6 +875,9 @@ static void rmi_input_configured(struct hid_device *hdev, struct hid_input *hi)
> if (ret)
> return;
>
> + if (!(data->device_flags & RMI_DEVICE))
> + return;
> +
> /* Allow incoming hid reports */
> hid_device_io_start(hdev);
>
> @@ -914,8 +936,33 @@ static int rmi_input_mapping(struct hid_device *hdev,
> struct hid_input *hi, struct hid_field *field,
> struct hid_usage *usage, unsigned long **bit, int *max)
> {
> - /* we want to make HID ignore the advertised HID collection */
> - return -1;
> + struct rmi_data *data = hid_get_drvdata(hdev);
> +
> + /*
> + * we want to make HID ignore the advertised HID collection
> + * for RMI deivces
> + */
> + if (data->device_flags & RMI_DEVICE)
> + return -1;
> +
> + return 0;
> +}
> +
> +static int rmi_check_valid_report_id(struct hid_device *hdev, unsigned type,
> + unsigned id, struct hid_report **report)
> +{
> + int i;
> +
> + *report = hdev->report_enum[type].report_id_hash[id];
> + if (*report) {
> + for (i = 0; i < (*report)->maxfield; i++) {
> + unsigned app = (*report)->field[i]->application;
> + if ((app & HID_USAGE_PAGE) >= HID_UP_MSVENDOR)
> + return 1;
> + }
> + }
> +
> + return 0;
> }
>
> static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id)
> @@ -925,6 +972,7 @@ static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id)
> size_t alloc_size;
> struct hid_report *input_report;
> struct hid_report *output_report;
> + struct hid_report *feature_report;
>
> data = devm_kzalloc(&hdev->dev, sizeof(struct rmi_data), GFP_KERNEL);
> if (!data)
> @@ -943,27 +991,35 @@ static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id)
> return ret;
> }
>
> - input_report = hdev->report_enum[HID_INPUT_REPORT]
> - .report_id_hash[RMI_ATTN_REPORT_ID];
> - if (!input_report) {
> - hid_err(hdev, "device does not have expected input report\n");
> - ret = -ENODEV;
> - return ret;
> + /*
> + * Check for the RMI specific report ids. If they are misisng
> + * simply return and let the events be processed by hid-input
> + */
> + if (!rmi_check_valid_report_id(hdev, HID_FEATURE_REPORT,
> + RMI_SET_RMI_MODE_REPORT_ID, &feature_report)) {
> + hid_dbg(hdev, "device does not have set mode feature report\n");
> + goto start;
> + }
> +
> + if (!rmi_check_valid_report_id(hdev, HID_INPUT_REPORT,
> + RMI_ATTN_REPORT_ID, &input_report)) {
> + hid_dbg(hdev, "device does not have attention input report\n");
> + goto start;
> }
>
> data->input_report_size = (input_report->size >> 3) + 1 /* report id */;
While you are at sending patches to fix hid-rmi, could you also try to
use hid_report_len() instead of manually computing the size (in a
separate patch if possible)?
I think the result should be the same, but I'd prefer you to double
check.
>
> - output_report = hdev->report_enum[HID_OUTPUT_REPORT]
> - .report_id_hash[RMI_WRITE_REPORT_ID];
> - if (!output_report) {
> - hid_err(hdev, "device does not have expected output report\n");
> - ret = -ENODEV;
> - return ret;
> + if (!rmi_check_valid_report_id(hdev, HID_OUTPUT_REPORT,
> + RMI_WRITE_REPORT_ID, &output_report)) {
> + hid_dbg(hdev,
> + "device does not have rmi write output report\n");
> + goto start;
> }
>
> data->output_report_size = (output_report->size >> 3)
> + 1 /* report id */;
>
ditto. hid_report_len() would be a nice cleaning.
> + data->device_flags |= RMI_DEVICE;
> alloc_size = data->output_report_size + data->input_report_size;
>
> data->writeReport = devm_kzalloc(&hdev->dev, alloc_size, GFP_KERNEL);
> @@ -978,13 +1034,15 @@ static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id)
>
> mutex_init(&data->page_mutex);
>
> +start:
> ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
> if (ret) {
> hid_err(hdev, "hw start failed\n");
> return ret;
> }
>
> - if (!test_bit(RMI_STARTED, &data->flags))
> + if ((data->device_flags & RMI_DEVICE) &&
> + !test_bit(RMI_STARTED, &data->flags))
> /*
> * The device maybe in the bootloader if rmi_input_configured
> * failed to find F11 in the PDT. Print an error, but don't
> @@ -1017,6 +1075,7 @@ static struct hid_driver rmi_driver = {
> .id_table = rmi_id,
> .probe = rmi_probe,
> .remove = rmi_remove,
> + .event = rmi_event,
> .raw_event = rmi_raw_event,
> .input_mapping = rmi_input_mapping,
> .input_configured = rmi_input_configured,
> --
> 2.1.0
>
Cheers,
Benjamin
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/3] HID: rmi: Support non rmi devices by passing events to hid-input
2014-12-19 22:45 [PATCH 1/3] HID: rmi: Support non rmi devices by passing events to hid-input Andrew Duggan
` (2 preceding siblings ...)
2014-12-20 1:42 ` [PATCH 1/3] HID: rmi: Support non rmi devices by passing events to hid-input Benjamin Tissoires
@ 2014-12-22 13:24 ` Jiri Kosina
3 siblings, 0 replies; 7+ messages in thread
From: Jiri Kosina @ 2014-12-22 13:24 UTC (permalink / raw)
To: Andrew Duggan; +Cc: linux-input, linux-kernel, Benjamin Tissoires
On Fri, 19 Dec 2014, Andrew Duggan wrote:
> Allowing hid-rmi to bind to non rmi devices allows us to support composite USB
> devices which contain several HID devices one of which is a HID touchpad.
> Since all of the devices have the same VID and PID we can add the device
> to the hid_have_special_driver list and have hid-rmi handle all of the devices.
> Then hid-rmi's probe can look for the rmi specific HID report IDs and decide if
> it should handle the device as a rmi device or simply report that the events
> needs additional processing.
>
> Signed-off-by: Andrew Duggan <aduggan@synaptics.com>
> ---
> This patch series is my second attempt at getting the hid-rmi driver working on
> the Razer Blade 14 based on Benjamin's comments. I decided to break it up into
> three separate patches. This one allows hid-rmi to bind to all of the devices.
> Instead of adding a quirk I just look at the report IDs to see if it should
> do rmi or not.
I have now applied 1/3, and waiting for v2 once you sort out with Benjamin
the comments he had.
Thanks,
--
Jiri Kosina
SUSE Labs
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2014-12-22 13:25 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-12-19 22:45 [PATCH 1/3] HID: rmi: Support non rmi devices by passing events to hid-input Andrew Duggan
2014-12-19 22:45 ` [PATCH 2/3] HID: rmi: Support touchpads with external buttons Andrew Duggan
2014-12-20 1:53 ` Benjamin Tissoires
2014-12-19 22:45 ` [PATCH 3/3] HID: rmi: Add support for the touchpad in the Razer Blade 14 laptop Andrew Duggan
2014-12-20 1:56 ` Benjamin Tissoires
2014-12-20 1:42 ` [PATCH 1/3] HID: rmi: Support non rmi devices by passing events to hid-input Benjamin Tissoires
2014-12-22 13:24 ` Jiri Kosina
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).