From patchwork Tue Dec 14 22:06:32 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Hooker X-Patchwork-Id: 75573 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from chlorine.canonical.com (chlorine.canonical.com [91.189.94.204]) by ozlabs.org (Postfix) with ESMTP id C793CB6F11 for ; Wed, 15 Dec 2010 09:06:41 +1100 (EST) Received: from localhost ([127.0.0.1] helo=chlorine.canonical.com) by chlorine.canonical.com with esmtp (Exim 4.69) (envelope-from ) id 1PSd13-0007a0-2S; Tue, 14 Dec 2010 22:06:37 +0000 Received: from mail-vw0-f49.google.com ([209.85.212.49]) by chlorine.canonical.com with esmtp (Exim 4.69) (envelope-from ) id 1PSd11-0007Zq-1e for kernel-team@lists.ubuntu.com; Tue, 14 Dec 2010 22:06:35 +0000 Received: by vws5 with SMTP id 5so511855vws.8 for ; Tue, 14 Dec 2010 14:06:34 -0800 (PST) Received: by 10.229.98.141 with SMTP id q13mr214137qcn.151.1292364394308; Tue, 14 Dec 2010 14:06:34 -0800 (PST) Received: from localhost (c-68-48-24-113.hsd1.va.comcast.net [68.48.24.113]) by mx.google.com with ESMTPS id y17sm264140qci.21.2010.12.14.14.06.33 (version=TLSv1/SSLv3 cipher=RC4-MD5); Tue, 14 Dec 2010 14:06:33 -0800 (PST) From: Robert Hooker To: kernel-team@lists.ubuntu.com Subject: [PATCH] UBUNTU: (pre-stable): input: Support Clickpad devices in ClickZone mode Date: Tue, 14 Dec 2010 17:06:32 -0500 Message-Id: <1292364392-6289-1-git-send-email-sarvatt@ubuntu.com> X-Mailer: git-send-email 1.7.2.3 In-Reply-To: <1292363299-5647-1-git-send-email-sarvatt@ubuntu.com> References: <1292363299-5647-1-git-send-email-sarvatt@ubuntu.com> X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.9 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: kernel-team-bounces@lists.ubuntu.com Errors-To: kernel-team-bounces@lists.ubuntu.com From: Takashi Iwai Add the experimental support of new Synatpics "Clickpad" devices. This device reports the click as the middle-button, but it doesn't set proper capability bits. Thus the driver needs to check the product-id and forces to enable the button detection. In this patch, the device behaves as "ClickZone" mode, and gives compatible events as other normal synaptics devices so that user-space app works as is. In the ClickZone mode, the buttons are emulated as clicks in the bottom button zone. Left and right clicks are judged by the touch position. Clicking the narrow middle point in the button zone gives a middle click. Dragging can be done by keeping the button down and touching the normal area again. Strangely, the sequence to click after touching the area doesn't work with this device by unknown reason... Signed-off-by: Takashi Iwai BugLink: http://bugs.launchpad.net/bugs/516329 Acked-by: Colin King Acked-by: Andy Whitcroft Signed-off-by: Chase Douglas Signed-off-by: Andy Whitcroft Fixed clickpad capability checks to only check the 0x0c cap. Signed-off-by: Robert Hooker Acked-by: Tim Gardner Acked-by: Brad Figg --- drivers/input/mouse/synaptics.c | 48 +++++++++++++++++++++++++++++++++++++++ drivers/input/mouse/synaptics.h | 1 + 2 files changed, 49 insertions(+), 0 deletions(-) diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 705589d..ae9891c 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -357,6 +357,45 @@ static void synaptics_pt_create(struct psmouse *psmouse) * Functions to interpret the absolute mode packets ****************************************************************************/ +/* left and right clickpad button ranges; + * the gap between them is interpreted as a middle-button click + */ +#define CLICKPAD_LEFT_BTN_X \ + ((XMAX_NOMINAL - XMIN_NOMINAL) * 2 / 5 + XMIN_NOMINAL) +#define CLICKPAD_RIGHT_BTN_X \ + ((XMAX_NOMINAL - XMIN_NOMINAL) * 3 / 5 + XMIN_NOMINAL) + +/* handle clickpad events */ +static void clickpad_process_packet(struct synaptics_data *priv, + struct synaptics_hw_state *hw) +{ + /* clickpad mode reports Y range from 0 to YMAX_NOMINAL, + * where the area Y < YMIN_NOMINAL is used as click buttons + */ + if (hw->y < YMIN_NOMINAL) { + /* button area */ + hw->z = 0; /* don't move pointer */ + /* clickpad reports only the middle button, and we need + * to fake left/right buttons depending on the touch position + */ + if (hw->middle) { /* clicked? */ + hw->middle = 0; + if (hw->x < CLICKPAD_LEFT_BTN_X) + hw->left = 1; + else if (hw->x > CLICKPAD_RIGHT_BTN_X) + hw->right = 1; + else + hw->middle = 1; + } + } else if (hw->middle) { + /* dragging */ + hw->left = priv->prev_hw.left; + hw->right = priv->prev_hw.right; + hw->middle = priv->prev_hw.middle; + } + priv->prev_hw = *hw; +} + static void synaptics_parse_hw_state(unsigned char buf[], struct synaptics_data *priv, struct synaptics_hw_state *hw) { memset(hw, 0, sizeof(struct synaptics_hw_state)); @@ -445,6 +484,9 @@ static void synaptics_process_packet(struct psmouse *psmouse) synaptics_parse_hw_state(psmouse->packet, priv, &hw); + if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) + clickpad_process_packet(priv, &hw); + if (hw.scroll) { priv->scroll += hw.scroll; @@ -748,6 +790,12 @@ int synaptics_init(struct psmouse *psmouse) SYN_ID_MAJOR(priv->identity), SYN_ID_MINOR(priv->identity), priv->model_id, priv->capabilities, priv->ext_cap, priv->ext_cap_0c); + if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) { + printk(KERN_INFO "Synaptics: Clickpad mode enabled\n"); + /* force to enable the middle button */ + priv->capabilities |= (1 << 18); + } + set_input_params(psmouse->dev, priv); /* diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h index b6aa7d2..80907d0 100644 --- a/drivers/input/mouse/synaptics.h +++ b/drivers/input/mouse/synaptics.h @@ -110,6 +110,7 @@ struct synaptics_data { unsigned char pkt_type; /* packet type - old, new, etc */ unsigned char mode; /* current mode byte */ int scroll; + struct synaptics_hw_state prev_hw; }; void synaptics_module_init(void);