From patchwork Thu Feb 9 19:49:11 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Torokhov X-Patchwork-Id: 9565405 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 063646020C for ; Thu, 9 Feb 2017 19:58:00 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EA45A28540 for ; Thu, 9 Feb 2017 19:57:59 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DDCCC28549; Thu, 9 Feb 2017 19:57:59 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.3 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM, T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 545E028540 for ; Thu, 9 Feb 2017 19:57:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932147AbdBIT5u (ORCPT ); Thu, 9 Feb 2017 14:57:50 -0500 Received: from mail-pg0-f67.google.com ([74.125.83.67]:34747 "EHLO mail-pg0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932421AbdBIT5t (ORCPT ); Thu, 9 Feb 2017 14:57:49 -0500 Received: by mail-pg0-f67.google.com with SMTP id v184so1100126pgv.1 for ; Thu, 09 Feb 2017 11:57:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=oy++yiG8Ael3l7obsB9xBYZf3xqvsxgoDT3GPgVlhZ0=; b=jQDSyk/jtYgavMwSnaCCvfuwjwEDL8NQa1VQmTBG1MXcO4fCQvjMv+muTCI14sdnMj n8WbD5a+/0xaD32UxwFiR3Ct44eGxwA6OWf2ZdH3YD0Z6zxQYPcYDO3FLteXYo7oDXvN 5sjfJmYOXb4Fv0ODOpAJ+MMlGVMvwLcEj2GA7PFN3whaQ677ejcPAXm2QrJRqlQStTOs pCIXH+OkWx+o6+P/Ozg5syp74/eXNyzsb56G8Ty3lNMDXtnRByj50yhHTPJOT1jw6zhz wMVJF0NWscBPQ/TW0AB/mcDNLiiyWJFpx/6ecK9ddku0SWVwGkWSbeBJIVbpiI4mKqeY NHEA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=oy++yiG8Ael3l7obsB9xBYZf3xqvsxgoDT3GPgVlhZ0=; b=Ys3gOwmF5U/8jk8O9YUl3JUgsJWDX4V1WGGgrapEyb9Svt3jWD2Xa1YFkDg9cnbVfv NkxONsUDlQ17aWbBc1uhIZqTSxC8h+j9LGamAXOqjYDDJpymZFRtgnRQfJpexsZvRhRQ /vnHr7VnbLPHn2axqSJl4cVEGkrzZgZFvzcbnCfpAgpuMis0pkVxk0rKbqpeExCsm6gN OZDcYp5qjk0cR6h5wol06DB4Qz111vYfDnZjp3q779g0TqercfqV0f1fHEfJ5VsWuVMf ZhYksP6zyO6gftv3s1bV0OBKcjMNuidc9f3Ea19o40mVMl5cohXdC4enmf50M2FGcT+A pN4w== X-Gm-Message-State: AMke39kRIUigspKii3MaYzIXvXfYdTknVxLHKXj/2eS/+q+lN6ap2qhlkyjy1Kp/FRam+A== X-Received: by 10.99.193.17 with SMTP id w17mr6039586pgf.124.1486669755681; Thu, 09 Feb 2017 11:49:15 -0800 (PST) Received: from dtor-ws.mtv.corp.google.com ([172.22.152.34]) by smtp.gmail.com with ESMTPSA id n70sm31016042pfg.34.2017.02.09.11.49.14 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 09 Feb 2017 11:49:15 -0800 (PST) From: Dmitry Torokhov To: Benjamin Tissoires Cc: Andrew Duggan , Christopher Heiny , Lyude Paul , linux-input@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 3/3] Input: synaptics-rmi4 - forward upper mechanical buttons to PS/2 guest Date: Thu, 9 Feb 2017 11:49:11 -0800 Message-Id: <20170209194911.32442-3-dmitry.torokhov@gmail.com> X-Mailer: git-send-email 2.11.0.483.g087da7b7c-goog In-Reply-To: <20170209194911.32442-1-dmitry.torokhov@gmail.com> References: <20170209194911.32442-1-dmitry.torokhov@gmail.com> Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Benjamin Tissoires 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 Signed-off-by: Benjamin Tissoires Patchwork-Id: 9560561 Signed-off-by: Dmitry Torokhov --- drivers/input/rmi4/rmi_driver.h | 13 ++++++++++ drivers/input/rmi4/rmi_f03.c | 38 ++++++++++++++++++++++++++++ drivers/input/rmi4/rmi_f30.c | 55 ++++++++++++++++++++++++++++++----------- 3 files changed, 91 insertions(+), 15 deletions(-) diff --git a/drivers/input/rmi4/rmi_driver.h b/drivers/input/rmi4/rmi_driver.h index 6e0449cdca68..f1a2a2266022 100644 --- a/drivers/input/rmi4/rmi_driver.h +++ b/drivers/input/rmi4/rmi_driver.h @@ -107,6 +107,19 @@ 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); diff --git a/drivers/input/rmi4/rmi_f03.c b/drivers/input/rmi4/rmi_f03.c index 9a1b099b72e0..77dad045a468 100644 --- a/drivers/input/rmi4/rmi_f03.c +++ b/drivers/input/rmi4/rmi_f03.c @@ -26,15 +26,53 @@ #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; + + if (button < BTN_LEFT || button > BTN_MIDDLE) + return -EINVAL; + + bit = BIT(button - BTN_LEFT); + + 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; + + 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 c5eb4d034e84..938d31eea19a 100644 --- a/drivers/input/rmi4/rmi_f30.c +++ b/drivers/input/rmi4/rmi_f30.c @@ -48,6 +48,9 @@ + 1 \ + 1) +#define TRACKSTICK_RANGE_START 3 +#define TRACKSTICK_RANGE_END 6 + struct rmi_f30_ctrl_data { int address; int length; @@ -76,6 +79,9 @@ struct f30_data { u16 *gpioled_key_map; struct input_dev *input; + + struct rmi_function *f03; + bool trackstick_buttons; }; static int rmi_f30_read_control_parameters(struct rmi_function *fn, @@ -100,13 +106,20 @@ static void rmi_f30_report_button(struct rmi_function *fn, { unsigned int reg_num = button >> 3; unsigned int bit_num = button & 0x07; + u16 key_code = f30->gpioled_key_map[button]; bool key_down = !(f30->data_regs[reg_num] & BIT(bit_num)); - rmi_dbg(RMI_DEBUG_FN, &fn->dev, - "%s: call input report key (0x%04x) value (0x%02x)", - __func__, f30->gpioled_key_map[button], key_down); + if (f30->trackstick_buttons && + button >= TRACKSTICK_RANGE_START && + button <= TRACKSTICK_RANGE_END) { + rmi_f03_overwrite_button(f30->f03, key_code, key_down); + } else { + rmi_dbg(RMI_DEBUG_FN, &fn->dev, + "%s: call input report key (0x%04x) value (0x%02x)", + __func__, key_code, key_down); - input_report_key(f30->input, f30->gpioled_key_map[button], key_down); + input_report_key(f30->input, key_code, key_down); + } } static int rmi_f30_attention(struct rmi_function *fn, unsigned long *irq_bits) @@ -154,6 +167,12 @@ static int rmi_f30_config(struct rmi_function *fn) rmi_get_platform_data(fn->rmi_dev); int error; + if (pdata->f30_data.trackstick_buttons) { + /* Try [re-]establish link to F03. */ + f30->f03 = rmi_find_function(fn->rmi_dev, 0x03); + f30->trackstick_buttons = f30->f03 != NULL; + } + if (pdata->f30_data.disable) { drv->clear_irq_bits(fn->rmi_dev, fn->irq_mask); } else { @@ -203,6 +222,8 @@ static int rmi_f30_map_gpios(struct rmi_function *fn, rmi_get_platform_data(fn->rmi_dev); struct input_dev *input = f30->input; unsigned int button = BTN_LEFT; + unsigned int trackstick_button = BTN_LEFT; + bool button_mapped = false; int i; f30->gpioled_key_map = devm_kcalloc(&fn->dev, @@ -215,19 +236,16 @@ static int rmi_f30_map_gpios(struct rmi_function *fn, } for (i = 0; i < f30->gpioled_count; i++) { - if (rmi_f30_is_valid_button(i, f30->ctrl)) { + if (!rmi_f30_is_valid_button(i, f30->ctrl)) + continue; + + if (pdata->f30_data.trackstick_buttons && + i >= TRACKSTICK_RANGE_START && i < TRACKSTICK_RANGE_END) { + f30->gpioled_key_map[i] = trackstick_button++; + } else if (!pdata->f30_data.buttonpad || !button_mapped) { f30->gpioled_key_map[i] = button; input_set_capability(input, EV_KEY, 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) { - __set_bit(INPUT_PROP_BUTTONPAD, input->propbit); - break; - } + button_mapped = true; } } @@ -235,6 +253,13 @@ static int rmi_f30_map_gpios(struct rmi_function *fn, input->keycodesize = sizeof(f30->gpioled_key_map[0]); input->keycodemax = f30->gpioled_count; + /* + * Buttonpad could be also inferred from f30->has_mech_mouse_btns, + * but I am not sure, so use only the pdata info. + */ + if (pdata->f30_data.buttonpad) + __set_bit(INPUT_PROP_BUTTONPAD, input->propbit); + return 0; }