Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1575088 > unrolled thread
| Started by | Dmitry Torokhov <dmitry.torokhov@gmail.com> |
|---|---|
| First post | 2017-02-06 20:30 +0100 |
| Last post | 2017-02-08 19:00 +0100 |
| Articles | 6 — 2 participants |
Back to article view | Back to linux.kernel
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
Re: [PATCH 03/10] Input: synaptics-rmi4 - f30/f03: Forward mechanical buttons on buttonpads to PS/2 guest Dmitry Torokhov <dmitry.torokhov@gmail.com> - 2017-02-06 20:30 +0100
Re: [PATCH 03/10] Input: synaptics-rmi4 - f30/f03: Forward mechanical buttons on buttonpads to PS/2 guest Benjamin Tissoires <benjamin.tissoires@redhat.com> - 2017-02-07 17:30 +0100
[PATCH v2 2/2] Input: synaptics-rmi4 - f30/f03: Forward mechanical buttons on buttonpads to PS/2 guest Benjamin Tissoires <benjamin.tissoires@redhat.com> - 2017-02-07 17:30 +0100
[PATCH v2 1/2] Input: psmouse - add a custom serio protocol to send extra information Benjamin Tissoires <benjamin.tissoires@redhat.com> - 2017-02-07 17:30 +0100
Re: [PATCH v2 1/2] Input: psmouse - add a custom serio protocol to send extra information Dmitry Torokhov <dmitry.torokhov@gmail.com> - 2017-02-08 09:30 +0100
Re: [PATCH v2 1/2] Input: psmouse - add a custom serio protocol to send extra information Benjamin Tissoires <benjamin.tissoires@redhat.com> - 2017-02-08 19:00 +0100
| From | Dmitry Torokhov <dmitry.torokhov@gmail.com> |
|---|---|
| Date | 2017-02-06 20:30 +0100 |
| Subject | Re: [PATCH 03/10] Input: synaptics-rmi4 - f30/f03: Forward mechanical buttons on buttonpads to PS/2 guest |
| Message-ID | <t7X97-Lb-9@gated-at.bofh.it> |
Hi Benjamin,
On Tue, Jan 10, 2017 at 05:11:21PM +0100, Benjamin Tissoires wrote:
> +void rmi_f03_commit_buttons(struct rmi_function *fn)
> +{
> + struct f03_data *f03 = dev_get_drvdata(&fn->dev);
> + int i;
> +
> + f03->serio->extra_byte = f03->overwrite_buttons;
> +
> + for (i = 0; i < 3; i++)
> + serio_interrupt(f03->serio, 0x00, 0x00);
How does this work with protocols larger than 3 bytes (i.e. anything but
bare PS/2)? Or F03 limits the kind of devices we connect to RMI4 device?
Overall, I am very uncomfortable with the concept of "extra byte" at
serio level. Maybe we should define a new flag, something like
SERIO_SYNTHETIC or SERIO_OOB_DATA, and have something like:
void rmi_f03_commit_buttons(struct rmi_function *fn)
{
struct serio *serio = f03->serio;
serio_pause_rx(serio);
if (serio->drv) {
serio->drv->interrupt(serio, PSMOUSE_EXTRA_BTNS,
SERIO_OOB_DATA);
serio->drv->interrupt(serio, f03->overwrite_buttons.
SERIO_OOB_DATA);
}
serio_pause_rx(serio);
}
and have psmouse driver store and use it as it sees fit.
Thanks.
--
Dmitry
[toc] | [next] | [standalone]
| From | Benjamin Tissoires <benjamin.tissoires@redhat.com> |
|---|---|
| Date | 2017-02-07 17:30 +0100 |
| Subject | Re: [PATCH 03/10] Input: synaptics-rmi4 - f30/f03: Forward mechanical buttons on buttonpads to PS/2 guest |
| Message-ID | <t8gOt-5dy-1@gated-at.bofh.it> |
| In reply to | #1575088 |
Hi Dmitry,
On Feb 06 2017 or thereabouts, Dmitry Torokhov wrote:
> Hi Benjamin,
>
> On Tue, Jan 10, 2017 at 05:11:21PM +0100, Benjamin Tissoires wrote:
> > +void rmi_f03_commit_buttons(struct rmi_function *fn)
> > +{
> > + struct f03_data *f03 = dev_get_drvdata(&fn->dev);
> > + int i;
> > +
> > + f03->serio->extra_byte = f03->overwrite_buttons;
> > +
> > + for (i = 0; i < 3; i++)
> > + serio_interrupt(f03->serio, 0x00, 0x00);
>
> How does this work with protocols larger than 3 bytes (i.e. anything but
> bare PS/2)? Or F03 limits the kind of devices we connect to RMI4 device?
Right, there is no such constraint.
>
> Overall, I am very uncomfortable with the concept of "extra byte" at
> serio level. Maybe we should define a new flag, something like
> SERIO_SYNTHETIC or SERIO_OOB_DATA, and have something like:
>
> void rmi_f03_commit_buttons(struct rmi_function *fn)
> {
> struct serio *serio = f03->serio;
>
> serio_pause_rx(serio);
> if (serio->drv) {
> serio->drv->interrupt(serio, PSMOUSE_EXTRA_BTNS,
> SERIO_OOB_DATA);
> serio->drv->interrupt(serio, f03->overwrite_buttons.
> SERIO_OOB_DATA);
> }
> serio_pause_rx(serio);
> }
>
> and have psmouse driver store and use it as it sees fit.
Sounds good to me. Would the 2 following patches be OK?
Cheers,
Benjamin
Benjamin Tissoires (2):
Input: psmouse - add a custom serio protocol to send extra information
Input: synaptics-rmi4 - f30/f03: Forward mechanical buttons on
buttonpads to PS/2 guest
drivers/input/mouse/psmouse-base.c | 39 +++++++++++++++++++--
drivers/input/mouse/psmouse.h | 5 +++
drivers/input/rmi4/rmi_driver.h | 14 ++++++++
drivers/input/rmi4/rmi_f03.c | 39 +++++++++++++++++++++
drivers/input/rmi4/rmi_f30.c | 72 ++++++++++++++++++++++++++++++--------
include/uapi/linux/serio.h | 7 ++--
6 files changed, 155 insertions(+), 21 deletions(-)
--
2.9.3
[toc] | [prev] | [next] | [standalone]
| From | Benjamin Tissoires <benjamin.tissoires@redhat.com> |
|---|---|
| Date | 2017-02-07 17:30 +0100 |
| Subject | [PATCH v2 2/2] Input: synaptics-rmi4 - f30/f03: Forward mechanical buttons on buttonpads to PS/2 guest |
| Message-ID | <t8gOt-5dy-9@gated-at.bofh.it> |
| In reply to | #1575850 |
On the latest series of ThinkPads, the button events for the TrackPoint
are reported through the touchpad itself as opposed to the TrackPoint
device. In order to report these buttons properly, we need to forward
them to the TrackPoint device and notify psmouse to send the button
presses/releases.
Signed-off-by: Lyude Paul <thatslyude@gmail.com>
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
Changes in v2:
- use of custom psmouse protocol with flag SERIO_OOB_DATA
drivers/input/rmi4/rmi_driver.h | 14 ++++++++
drivers/input/rmi4/rmi_f03.c | 39 ++++++++++++++++++++++
drivers/input/rmi4/rmi_f30.c | 72 ++++++++++++++++++++++++++++++++---------
3 files changed, 110 insertions(+), 15 deletions(-)
diff --git a/drivers/input/rmi4/rmi_driver.h b/drivers/input/rmi4/rmi_driver.h
index 6e0449c..d2a89ed 100644
--- a/drivers/input/rmi4/rmi_driver.h
+++ b/drivers/input/rmi4/rmi_driver.h
@@ -107,7 +107,21 @@ int rmi_initial_reset(struct rmi_device *rmi_dev, void *ctx,
const char *rmi_f01_get_product_ID(struct rmi_function *fn);
+#ifdef CONFIG_RMI4_F03
+int rmi_f03_overwrite_button(struct rmi_function *fn, unsigned int button,
+ int value);
+void rmi_f03_commit_buttons(struct rmi_function *fn);
+#else
+static inline int rmi_f03_overwrite_button(struct rmi_function *fn,
+ unsigned int button, int value)
+{
+ return 0;
+}
+static inline void rmi_f03_commit_buttons(struct rmi_function *fn) {}
+#endif
+
#ifdef CONFIG_RMI4_F34
+
int rmi_f34_create_sysfs(struct rmi_device *rmi_dev);
void rmi_f34_remove_sysfs(struct rmi_device *rmi_dev);
#else
diff --git a/drivers/input/rmi4/rmi_f03.c b/drivers/input/rmi4/rmi_f03.c
index 9a1b099..c89137a 100644
--- a/drivers/input/rmi4/rmi_f03.c
+++ b/drivers/input/rmi4/rmi_f03.c
@@ -26,15 +26,54 @@
#define RMI_F03_BYTES_PER_DEVICE_SHIFT 4
#define RMI_F03_QUEUE_LENGTH 0x0F
+#define PSMOUSE_OOB_EXTRA_BTNS 0x01
+
struct f03_data {
struct rmi_function *fn;
struct serio *serio;
+ unsigned int overwrite_buttons;
+
u8 device_count;
u8 rx_queue_length;
};
+int rmi_f03_overwrite_button(struct rmi_function *fn, unsigned int button,
+ int value)
+{
+ struct f03_data *f03 = dev_get_drvdata(&fn->dev);
+ unsigned int bit = BIT(button);
+
+ if (button > 2)
+ return -EINVAL;
+
+ if (value)
+ f03->overwrite_buttons |= bit;
+ else
+ f03->overwrite_buttons &= ~bit;
+
+ return 0;
+}
+
+void rmi_f03_commit_buttons(struct rmi_function *fn)
+{
+ struct f03_data *f03 = dev_get_drvdata(&fn->dev);
+ struct serio *serio = f03->serio;
+
+ if (!serio)
+ return;
+
+ serio_pause_rx(serio);
+ if (serio->drv) {
+ serio->drv->interrupt(serio, PSMOUSE_OOB_EXTRA_BTNS,
+ SERIO_OOB_DATA);
+ serio->drv->interrupt(serio, f03->overwrite_buttons,
+ SERIO_OOB_DATA);
+ }
+ serio_continue_rx(serio);
+}
+
static int rmi_f03_pt_write(struct serio *id, unsigned char val)
{
struct f03_data *f03 = id->port_data;
diff --git a/drivers/input/rmi4/rmi_f30.c b/drivers/input/rmi4/rmi_f30.c
index f4b491e..608c5ee 100644
--- a/drivers/input/rmi4/rmi_f30.c
+++ b/drivers/input/rmi4/rmi_f30.c
@@ -74,8 +74,11 @@ struct f30_data {
u8 data_regs[RMI_F30_CTRL_MAX_BYTES];
u16 *gpioled_key_map;
+ u16 *gpio_passthrough_key_map;
struct input_dev *input;
+ bool trackstick_buttons;
+ struct rmi_function *f03;
};
static int rmi_f30_read_control_parameters(struct rmi_function *fn,
@@ -109,6 +112,13 @@ static int rmi_f30_attention(struct rmi_function *fn, unsigned long *irq_bits)
if (!f30->input)
return 0;
+ if (f30->trackstick_buttons && !f30->f03) {
+ f30->f03 = rmi_find_function(rmi_dev, 3);
+
+ if (!f30->f03)
+ return -EBUSY;
+ }
+
/* Read the gpi led data. */
if (drvdata->attn_data.data) {
if (drvdata->attn_data.size < f30->register_count) {
@@ -133,23 +143,29 @@ static int rmi_f30_attention(struct rmi_function *fn, unsigned long *irq_bits)
for (reg_num = 0; reg_num < f30->register_count; ++reg_num) {
for (i = 0; gpiled < f30->gpioled_count && i < 8; ++i,
++gpiled) {
- if (f30->gpioled_key_map[gpiled] != 0) {
- /* buttons have pull up resistors */
- value = (((f30->data_regs[reg_num] >> i) & 0x01)
- == 0);
+ /* buttons have pull up resistors */
+ value = (((f30->data_regs[reg_num] >> i) & 0x01) == 0);
+ if (f30->gpioled_key_map[gpiled] != 0) {
rmi_dbg(RMI_DEBUG_FN, &fn->dev,
"%s: call input report key (0x%04x) value (0x%02x)",
__func__,
f30->gpioled_key_map[gpiled], value);
+
input_report_key(f30->input,
f30->gpioled_key_map[gpiled],
value);
+ } else if (f30->gpio_passthrough_key_map[gpiled]) {
+ rmi_f03_overwrite_button(f30->f03,
+ f30->gpio_passthrough_key_map[gpiled] - BTN_LEFT,
+ value);
}
-
}
}
+ if (f30->trackstick_buttons)
+ rmi_f03_commit_buttons(f30->f03);
+
return 0;
}
@@ -247,10 +263,11 @@ static inline int rmi_f30_initialize(struct rmi_function *fn)
int retval = 0;
int control_address;
int i;
- int button;
+ int button, extra_button;
u8 buf[RMI_F30_QUERY_SIZE];
u8 *ctrl_reg;
- u8 *map_memory;
+ u8 *map_memory, *pt_memory;
+ bool buttonpad;
f30 = devm_kzalloc(&fn->dev, sizeof(struct f30_data),
GFP_KERNEL);
@@ -348,29 +365,54 @@ static inline int rmi_f30_initialize(struct rmi_function *fn)
map_memory = devm_kzalloc(&fn->dev,
(f30->gpioled_count * (sizeof(u16))),
GFP_KERNEL);
- if (!map_memory) {
+ pt_memory = devm_kzalloc(&fn->dev,
+ (f30->gpioled_count * (sizeof(u16))),
+ GFP_KERNEL);
+ if (!map_memory || !pt_memory) {
dev_err(&fn->dev, "Failed to allocate gpioled map memory.\n");
return -ENOMEM;
}
f30->gpioled_key_map = (u16 *)map_memory;
+ f30->gpio_passthrough_key_map = (u16 *)pt_memory;
pdata = rmi_get_platform_data(rmi_dev);
if (f30->has_gpio) {
+ /*
+ * buttonpad might be given by f30->has_mech_mouse_btns,
+ * but I am not sure, so use only the pdata info
+ */
+ buttonpad = pdata->f30_data.buttonpad;
+ f30->trackstick_buttons = pdata->f30_data.trackstick_buttons;
+
+ /*
+ * For touchpads the buttons are mapped as:
+ * - bit 0 = Left, bit 1 = right, bit 2 = middle / clickbutton
+ * - 3, 4, 5 are extended buttons and
+ * - 6 and 7 are other sorts of GPIOs
+ */
button = BTN_LEFT;
- for (i = 0; i < f30->gpioled_count; i++) {
+ extra_button = BTN_LEFT;
+ for (i = 0; i < f30->gpioled_count && i < 3; i++) {
if (rmi_f30_is_valid_button(i, f30->ctrl)) {
f30->gpioled_key_map[i] = button++;
- /*
- * buttonpad might be given by
- * f30->has_mech_mouse_btns, but I am
- * not sure, so use only the pdata info
- */
- if (pdata->f30_data.buttonpad)
+ if (buttonpad)
break;
}
}
+
+ if (f30->trackstick_buttons) {
+ for (i = 3; i < f30->gpioled_count && i < 6; i++) {
+ if (rmi_f30_is_valid_button(i, f30->ctrl))
+ f30->gpio_passthrough_key_map[i] = extra_button++;
+ }
+ } else if (!buttonpad) {
+ for (i = 3; i < f30->gpioled_count; i++) {
+ if (rmi_f30_is_valid_button(i, f30->ctrl))
+ f30->gpioled_key_map[i] = button++;
+ }
+ }
}
return 0;
--
2.9.3
[toc] | [prev] | [next] | [standalone]
| From | Benjamin Tissoires <benjamin.tissoires@redhat.com> |
|---|---|
| Date | 2017-02-07 17:30 +0100 |
| Subject | [PATCH v2 1/2] Input: psmouse - add a custom serio protocol to send extra information |
| Message-ID | <t8gOt-5dy-3@gated-at.bofh.it> |
| In reply to | #1575850 |
The tracksticks on the Lenovo thinkpads have their buttons connected
through the touchpad device. We already fixed that in synaptics.c, but
when we switch the device into RMI4 mode to have proper support, the
pass-through functionality can't deal with them easily.
We add a new PS/2 flag and protocol designed for psmouse.
The RMI4 F03 pass-through can then emit a special set of commands
to notify psmouse the state of the buttons.
This patch implements the protocol in psmouse, while an other will
do the same for rmi4-f03.
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
drivers/input/mouse/psmouse-base.c | 39 +++++++++++++++++++++++++++++++++++---
drivers/input/mouse/psmouse.h | 5 +++++
include/uapi/linux/serio.h | 7 ++++---
3 files changed, 45 insertions(+), 6 deletions(-)
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index bee2674..d37b04a 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -199,9 +199,12 @@ psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse)
}
/* Generic PS/2 Mouse */
- input_report_key(dev, BTN_LEFT, packet[0] & 1);
- input_report_key(dev, BTN_MIDDLE, (packet[0] >> 2) & 1);
- input_report_key(dev, BTN_RIGHT, (packet[0] >> 1) & 1);
+ input_report_key(dev, BTN_LEFT,
+ (packet[0] | psmouse->extra_buttons) & 1);
+ input_report_key(dev, BTN_MIDDLE,
+ ((packet[0] | psmouse->extra_buttons) >> 2) & 1);
+ input_report_key(dev, BTN_RIGHT,
+ ((packet[0] | psmouse->extra_buttons) >> 1) & 1);
input_report_rel(dev, REL_X, packet[1] ? (int) packet[1] - (int) ((packet[0] << 4) & 0x100) : 0);
input_report_rel(dev, REL_Y, packet[2] ? (int) ((packet[0] << 3) & 0x100) - (int) packet[2] : 0);
@@ -282,6 +285,19 @@ static int psmouse_handle_byte(struct psmouse *psmouse)
return 0;
}
+static void psmouse_handle_extra_buttons(struct psmouse *psmouse,
+ unsigned char data)
+{
+ struct input_dev *dev = psmouse->dev;
+
+ input_report_key(dev, BTN_LEFT, data & 1);
+ input_report_key(dev, BTN_MIDDLE, (data >> 2) & 1);
+ input_report_key(dev, BTN_RIGHT, (data >> 1) & 1);
+ input_sync(dev);
+
+ psmouse->extra_buttons = data;
+}
+
/*
* psmouse_interrupt() handles incoming characters, either passing them
* for normal processing or gathering them as command response.
@@ -306,6 +322,23 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
goto out;
}
+ if (unlikely(flags & SERIO_OOB_DATA)) {
+ switch (psmouse->oob_data_type) {
+ case PSMOUSE_OOB_NONE:
+ psmouse->oob_data_type = data;
+ goto out;
+ case PSMOUSE_OOB_EXTRA_BTNS:
+ psmouse_handle_extra_buttons(psmouse, data);
+ psmouse->oob_data_type = PSMOUSE_OOB_NONE;
+ goto out;
+ default:
+ psmouse_warn(psmouse,
+ "unknown OOB_DATA type: 0x%02x\n",
+ psmouse->oob_data_type);
+ psmouse->oob_data_type = PSMOUSE_OOB_NONE;
+ }
+ }
+
if (unlikely(psmouse->ps2dev.flags & PS2_FLAG_ACK))
if (ps2_handle_ack(&psmouse->ps2dev, data))
goto out;
diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
index e0ca6cd..8c83b8e 100644
--- a/drivers/input/mouse/psmouse.h
+++ b/drivers/input/mouse/psmouse.h
@@ -1,6 +1,9 @@
#ifndef _PSMOUSE_H
#define _PSMOUSE_H
+#define PSMOUSE_OOB_NONE 0x00
+#define PSMOUSE_OOB_EXTRA_BTNS 0x01
+
#define PSMOUSE_CMD_SETSCALE11 0x00e6
#define PSMOUSE_CMD_SETSCALE21 0x00e7
#define PSMOUSE_CMD_SETRES 0x10e8
@@ -53,6 +56,8 @@ struct psmouse {
unsigned char pktcnt;
unsigned char pktsize;
unsigned char type;
+ unsigned char oob_data_type;
+ unsigned char extra_buttons;
bool ignore_parity;
bool acks_disable_command;
unsigned int model;
diff --git a/include/uapi/linux/serio.h b/include/uapi/linux/serio.h
index f2447a8..ccd0ccd 100644
--- a/include/uapi/linux/serio.h
+++ b/include/uapi/linux/serio.h
@@ -17,9 +17,10 @@
/*
* bit masks for use in "interrupt" flags (3rd argument)
*/
-#define SERIO_TIMEOUT 1
-#define SERIO_PARITY 2
-#define SERIO_FRAME 4
+#define SERIO_TIMEOUT BIT(0)
+#define SERIO_PARITY BIT(1)
+#define SERIO_FRAME BIT(2)
+#define SERIO_OOB_DATA BIT(3)
/*
* Serio types
--
2.9.3
[toc] | [prev] | [next] | [standalone]
| From | Dmitry Torokhov <dmitry.torokhov@gmail.com> |
|---|---|
| Date | 2017-02-08 09:30 +0100 |
| Subject | Re: [PATCH v2 1/2] Input: psmouse - add a custom serio protocol to send extra information |
| Message-ID | <t8vNv-6lj-3@gated-at.bofh.it> |
| In reply to | #1575856 |
On Tue, Feb 07, 2017 at 05:25:38PM +0100, Benjamin Tissoires wrote:
> The tracksticks on the Lenovo thinkpads have their buttons connected
> through the touchpad device. We already fixed that in synaptics.c, but
> when we switch the device into RMI4 mode to have proper support, the
> pass-through functionality can't deal with them easily.
>
> We add a new PS/2 flag and protocol designed for psmouse.
> The RMI4 F03 pass-through can then emit a special set of commands
> to notify psmouse the state of the buttons.
>
> This patch implements the protocol in psmouse, while an other will
> do the same for rmi4-f03.
>
> Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Looks mostly good, but how about this one?
Thanks.
--
Dmitry
Input: psmouse - add a custom serio protocol to send extra information
From: Benjamin Tissoires <benjamin.tissoires@redhat.com>
The tracksticks on the Lenovo thinkpads have their buttons connected
through the touchpad device. We already fixed that in synaptics.c, but
when we switch the device into RMI4 mode to have proper support, the
pass-through functionality can't deal with them easily.
We add a new PS/2 flag and protocol designed for psmouse. The RMI4 F03
pass-through can then emit a special set of commands to notify psmouse the
state of the buttons.
This patch implements the protocol in psmouse, while an other will
do the same for rmi4-f03.
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Patchwork-Id: 9560567
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
drivers/input/mouse/psmouse-base.c | 39 +++++++++++++++++++++++++++++++++---
drivers/input/mouse/psmouse.h | 5 +++++
include/uapi/linux/serio.h | 7 ++++--
3 files changed, 45 insertions(+), 6 deletions(-)
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index bee267424972..98a34105d5b0 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -127,6 +127,13 @@ struct psmouse_protocol {
int (*init)(struct psmouse *);
};
+static void psmouse_report_standard_buttons(struct input_dev *dev, u8 buttons)
+{
+ input_report_key(dev, BTN_LEFT, buttons & BIT(0));
+ input_report_key(dev, BTN_MIDDLE, buttons & BIT(2));
+ input_report_key(dev, BTN_RIGHT, buttons & BIT(1));
+}
+
/*
* psmouse_process_byte() analyzes the PS/2 data stream and reports
* relevant events to the input module once full packet has arrived.
@@ -199,9 +206,8 @@ psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse)
}
/* Generic PS/2 Mouse */
- input_report_key(dev, BTN_LEFT, packet[0] & 1);
- input_report_key(dev, BTN_MIDDLE, (packet[0] >> 2) & 1);
- input_report_key(dev, BTN_RIGHT, (packet[0] >> 1) & 1);
+ psmouse_report_standard_buttons(dev,
+ packet[0] | psmouse->extra_buttons);
input_report_rel(dev, REL_X, packet[1] ? (int) packet[1] - (int) ((packet[0] << 4) & 0x100) : 0);
input_report_rel(dev, REL_Y, packet[2] ? (int) ((packet[0] << 3) & 0x100) - (int) packet[2] : 0);
@@ -282,6 +288,28 @@ static int psmouse_handle_byte(struct psmouse *psmouse)
return 0;
}
+static void psmouse_handle_oob_data(struct psmouse *psmouse, u8 data)
+{
+ switch (psmouse->oob_data_type) {
+ case PSMOUSE_OOB_NONE:
+ psmouse->oob_data_type = data;
+ break;
+
+ case PSMOUSE_OOB_EXTRA_BTNS:
+ psmouse_report_standard_buttons(psmouse->dev, data);
+ psmouse->extra_buttons = data;
+ psmouse->oob_data_type = PSMOUSE_OOB_NONE;
+ break;
+
+ default:
+ psmouse_warn(psmouse,
+ "unknown OOB_DATA type: 0x%02x\n",
+ psmouse->oob_data_type);
+ psmouse->oob_data_type = PSMOUSE_OOB_NONE;
+ break;
+ }
+}
+
/*
* psmouse_interrupt() handles incoming characters, either passing them
* for normal processing or gathering them as command response.
@@ -306,6 +334,11 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
goto out;
}
+ if (flags & SERIO_OOB_DATA) {
+ psmouse_handle_oob_data(psmouse, data);
+ goto out;
+ }
+
if (unlikely(psmouse->ps2dev.flags & PS2_FLAG_ACK))
if (ps2_handle_ack(&psmouse->ps2dev, data))
goto out;
diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
index e0ca6cda3d16..8c83b8e2505c 100644
--- a/drivers/input/mouse/psmouse.h
+++ b/drivers/input/mouse/psmouse.h
@@ -1,6 +1,9 @@
#ifndef _PSMOUSE_H
#define _PSMOUSE_H
+#define PSMOUSE_OOB_NONE 0x00
+#define PSMOUSE_OOB_EXTRA_BTNS 0x01
+
#define PSMOUSE_CMD_SETSCALE11 0x00e6
#define PSMOUSE_CMD_SETSCALE21 0x00e7
#define PSMOUSE_CMD_SETRES 0x10e8
@@ -53,6 +56,8 @@ struct psmouse {
unsigned char pktcnt;
unsigned char pktsize;
unsigned char type;
+ unsigned char oob_data_type;
+ unsigned char extra_buttons;
bool ignore_parity;
bool acks_disable_command;
unsigned int model;
diff --git a/include/uapi/linux/serio.h b/include/uapi/linux/serio.h
index f2447a83ac8d..ccd0ccd00f47 100644
--- a/include/uapi/linux/serio.h
+++ b/include/uapi/linux/serio.h
@@ -17,9 +17,10 @@
/*
* bit masks for use in "interrupt" flags (3rd argument)
*/
-#define SERIO_TIMEOUT 1
-#define SERIO_PARITY 2
-#define SERIO_FRAME 4
+#define SERIO_TIMEOUT BIT(0)
+#define SERIO_PARITY BIT(1)
+#define SERIO_FRAME BIT(2)
+#define SERIO_OOB_DATA BIT(3)
/*
* Serio types
[toc] | [prev] | [next] | [standalone]
| From | Benjamin Tissoires <benjamin.tissoires@redhat.com> |
|---|---|
| Date | 2017-02-08 19:00 +0100 |
| Subject | Re: [PATCH v2 1/2] Input: psmouse - add a custom serio protocol to send extra information |
| Message-ID | <t8EH8-3ls-11@gated-at.bofh.it> |
| In reply to | #1576335 |
On Feb 08 2017 or thereabouts, Dmitry Torokhov wrote:
> On Tue, Feb 07, 2017 at 05:25:38PM +0100, Benjamin Tissoires wrote:
> > The tracksticks on the Lenovo thinkpads have their buttons connected
> > through the touchpad device. We already fixed that in synaptics.c, but
> > when we switch the device into RMI4 mode to have proper support, the
> > pass-through functionality can't deal with them easily.
> >
> > We add a new PS/2 flag and protocol designed for psmouse.
> > The RMI4 F03 pass-through can then emit a special set of commands
> > to notify psmouse the state of the buttons.
> >
> > This patch implements the protocol in psmouse, while an other will
> > do the same for rmi4-f03.
> >
> > Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
>
> Looks mostly good, but how about this one?
Thanks for the fix. There is one missing input_sync() in the OOB_DATA
case:
>
> Thanks.
>
> --
> Dmitry
>
>
> Input: psmouse - add a custom serio protocol to send extra information
>
> From: Benjamin Tissoires <benjamin.tissoires@redhat.com>
>
> The tracksticks on the Lenovo thinkpads have their buttons connected
> through the touchpad device. We already fixed that in synaptics.c, but
> when we switch the device into RMI4 mode to have proper support, the
> pass-through functionality can't deal with them easily.
>
> We add a new PS/2 flag and protocol designed for psmouse. The RMI4 F03
> pass-through can then emit a special set of commands to notify psmouse the
> state of the buttons.
>
> This patch implements the protocol in psmouse, while an other will
> do the same for rmi4-f03.
>
> Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
> Patchwork-Id: 9560567
> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> ---
> drivers/input/mouse/psmouse-base.c | 39 +++++++++++++++++++++++++++++++++---
> drivers/input/mouse/psmouse.h | 5 +++++
> include/uapi/linux/serio.h | 7 ++++--
> 3 files changed, 45 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
> index bee267424972..98a34105d5b0 100644
> --- a/drivers/input/mouse/psmouse-base.c
> +++ b/drivers/input/mouse/psmouse-base.c
> @@ -127,6 +127,13 @@ struct psmouse_protocol {
> int (*init)(struct psmouse *);
> };
>
> +static void psmouse_report_standard_buttons(struct input_dev *dev, u8 buttons)
> +{
> + input_report_key(dev, BTN_LEFT, buttons & BIT(0));
> + input_report_key(dev, BTN_MIDDLE, buttons & BIT(2));
> + input_report_key(dev, BTN_RIGHT, buttons & BIT(1));
> +}
> +
> /*
> * psmouse_process_byte() analyzes the PS/2 data stream and reports
> * relevant events to the input module once full packet has arrived.
> @@ -199,9 +206,8 @@ psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse)
> }
>
> /* Generic PS/2 Mouse */
> - input_report_key(dev, BTN_LEFT, packet[0] & 1);
> - input_report_key(dev, BTN_MIDDLE, (packet[0] >> 2) & 1);
> - input_report_key(dev, BTN_RIGHT, (packet[0] >> 1) & 1);
> + psmouse_report_standard_buttons(dev,
> + packet[0] | psmouse->extra_buttons);
>
> input_report_rel(dev, REL_X, packet[1] ? (int) packet[1] - (int) ((packet[0] << 4) & 0x100) : 0);
> input_report_rel(dev, REL_Y, packet[2] ? (int) ((packet[0] << 3) & 0x100) - (int) packet[2] : 0);
> @@ -282,6 +288,28 @@ static int psmouse_handle_byte(struct psmouse *psmouse)
> return 0;
> }
>
> +static void psmouse_handle_oob_data(struct psmouse *psmouse, u8 data)
> +{
> + switch (psmouse->oob_data_type) {
> + case PSMOUSE_OOB_NONE:
> + psmouse->oob_data_type = data;
> + break;
> +
> + case PSMOUSE_OOB_EXTRA_BTNS:
> + psmouse_report_standard_buttons(psmouse->dev, data);
We should probably call input_sync(psmouse->dev) here or the buttons are
not forwarded until the trackstick gets touched.
With that fix:
Tested-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Cheers,
Benjamin
PS: I won't have the time to work on the other issues of the series this
week unfortunately :(
> + psmouse->extra_buttons = data;
> + psmouse->oob_data_type = PSMOUSE_OOB_NONE;
> + break;
> +
> + default:
> + psmouse_warn(psmouse,
> + "unknown OOB_DATA type: 0x%02x\n",
> + psmouse->oob_data_type);
> + psmouse->oob_data_type = PSMOUSE_OOB_NONE;
> + break;
> + }
> +}
> +
> /*
> * psmouse_interrupt() handles incoming characters, either passing them
> * for normal processing or gathering them as command response.
> @@ -306,6 +334,11 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
> goto out;
> }
>
> + if (flags & SERIO_OOB_DATA) {
> + psmouse_handle_oob_data(psmouse, data);
> + goto out;
> + }
> +
> if (unlikely(psmouse->ps2dev.flags & PS2_FLAG_ACK))
> if (ps2_handle_ack(&psmouse->ps2dev, data))
> goto out;
> diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
> index e0ca6cda3d16..8c83b8e2505c 100644
> --- a/drivers/input/mouse/psmouse.h
> +++ b/drivers/input/mouse/psmouse.h
> @@ -1,6 +1,9 @@
> #ifndef _PSMOUSE_H
> #define _PSMOUSE_H
>
> +#define PSMOUSE_OOB_NONE 0x00
> +#define PSMOUSE_OOB_EXTRA_BTNS 0x01
> +
> #define PSMOUSE_CMD_SETSCALE11 0x00e6
> #define PSMOUSE_CMD_SETSCALE21 0x00e7
> #define PSMOUSE_CMD_SETRES 0x10e8
> @@ -53,6 +56,8 @@ struct psmouse {
> unsigned char pktcnt;
> unsigned char pktsize;
> unsigned char type;
> + unsigned char oob_data_type;
> + unsigned char extra_buttons;
> bool ignore_parity;
> bool acks_disable_command;
> unsigned int model;
> diff --git a/include/uapi/linux/serio.h b/include/uapi/linux/serio.h
> index f2447a83ac8d..ccd0ccd00f47 100644
> --- a/include/uapi/linux/serio.h
> +++ b/include/uapi/linux/serio.h
> @@ -17,9 +17,10 @@
> /*
> * bit masks for use in "interrupt" flags (3rd argument)
> */
> -#define SERIO_TIMEOUT 1
> -#define SERIO_PARITY 2
> -#define SERIO_FRAME 4
> +#define SERIO_TIMEOUT BIT(0)
> +#define SERIO_PARITY BIT(1)
> +#define SERIO_FRAME BIT(2)
> +#define SERIO_OOB_DATA BIT(3)
>
> /*
> * Serio types
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web