From patchwork Tue Dec 15 06:26:28 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Torokhov X-Patchwork-Id: 67529 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id nBF6QbMP032068 for ; Tue, 15 Dec 2009 06:26:37 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754151AbZLOG0g (ORCPT ); Tue, 15 Dec 2009 01:26:36 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1754146AbZLOG0g (ORCPT ); Tue, 15 Dec 2009 01:26:36 -0500 Received: from mail-px0-f174.google.com ([209.85.216.174]:38474 "EHLO mail-px0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753859AbZLOG0f (ORCPT ); Tue, 15 Dec 2009 01:26:35 -0500 Received: by pxi4 with SMTP id 4so2381153pxi.33 for ; Mon, 14 Dec 2009 22:26:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:date:from:to:cc:subject :message-id:references:mime-version:content-type:content-disposition :in-reply-to:user-agent; bh=WbrjwgV8L9R9Zy78r2WfJ9M+mqaWKfRazBi0HVLKJWM=; b=Pf4MqxlCM5b2zRFYYx/iv+JqBa13gJd6lyqoAc1qSqhyXJcTlNQADEvcyIBaU9MHKk mN3oh373HWEzIiLJsb7GZh30IdejrNjooG4FHawOaSd9jJ7R32DkVdxhruQ+e/DuB8lj Y//dBdyxu+7ni42DCbBUaPK/GROQvGSeauMtA= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=date:from:to:cc:subject:message-id:references:mime-version :content-type:content-disposition:in-reply-to:user-agent; b=PmP/CtAtyYL70HmCnnVL479gyP9Kf0DbYnDOBybjPQ1nZibHTN00Mbv0lFclySYrJf pHO90Xzhabfy+6GfHnepGbXM4iQog/aX15xF95bOxO8zPnTx9P25qvVCwbPEYLZA5isI I+gdpPkrMg52gwegvWekkemYAqH0PXP9udnqI= Received: by 10.114.214.24 with SMTP id m24mr3996011wag.93.1260858394270; Mon, 14 Dec 2009 22:26:34 -0800 (PST) Received: from mailhub.coreip.homeip.net (c-24-6-153-137.hsd1.ca.comcast.net [24.6.153.137]) by mx.google.com with ESMTPS id 23sm5648949pzk.4.2009.12.14.22.26.32 (version=TLSv1/SSLv3 cipher=RC4-MD5); Mon, 14 Dec 2009 22:26:32 -0800 (PST) Date: Mon, 14 Dec 2009 22:26:28 -0800 From: Dmitry Torokhov To: Alex Chiang Cc: tiwai@suse.de, linux-kernel , linux-input@vger.kernel.org Subject: Re: synaptics touchpad doesn't click Message-ID: <20091215062628.GA12669@core.coreip.homeip.net> References: <20091214014828.GA28402@ldl.fc.hp.com> <20091214173450.GB2373@core.coreip.homeip.net> <20091215034127.GC587@ldl.fc.hp.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20091215034127.GC587@ldl.fc.hp.com> User-Agent: Mutt/1.5.19 (2009-01-05) Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org different patch below (I did not quite like that the original patch mangled device's capability field and how it was reusing 'middle' field for different things)? It should apply on top of patch that I am attaching. I hope I did not screw it up too much, Thanks a lot. -- Dmitry Input: synaptics - add support for ClickPad devices From: Takashi Iwai The new device is a button-less "clickable" touchpad, the touchpad click is signaled the same way middle button click is signalled on touchpads that have SYN_CAP_MIDDLE_BUTTON capability. The touchpad will be working in what Synaptics calls "ClickZone" mode where left, right and middle buttons are emulated as clicks in the bottom button zone, depending on the touch position. Dragging can be done by keeping the button down and touching the main area again. Unfortunately the device does not signal clicks when main area is touched first. Due to the fact that there is no known capability bits for ClickPads we are forced to match on product ID. Signed-off-by: Takashi Iwai Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/synaptics.c | 59 ++++++++++++++++++++++++++++++++++----- drivers/input/mouse/synaptics.h | 2 + 2 files changed, 53 insertions(+), 8 deletions(-) diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 0d60cb7..d11a673 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -41,6 +41,15 @@ #define YMIN_NOMINAL 1408 #define YMAX_NOMINAL 4448 +/* + * Left and right ClickPad button ranges; the gap between them is reserved + * for middle button. + */ +#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) + /***************************************************************************** * Stuff we need even when we do not want native Synaptics support @@ -330,20 +339,52 @@ static void synaptics_parse_new_hw(unsigned char buf[], struct synaptics_data *priv, struct synaptics_hw_state *hw) { - hw->x = (((buf[3] & 0x10) << 8) | ((buf[1] & 0x0f) << 8) | buf[4]); - hw->y = (((buf[3] & 0x20) << 7) | ((buf[1] & 0xf0) << 4) | buf[5]); + int x = (((buf[3] & 0x10) << 8) | ((buf[1] & 0x0f) << 8) | buf[4]); + int y = (((buf[3] & 0x20) << 7) | ((buf[1] & 0xf0) << 4) | buf[5]); hw->z = buf[2]; hw->w = (((buf[0] & 0x30) >> 2) | ((buf[0] & 0x04) >> 1) | ((buf[3] & 0x04) >> 2)); - hw->left = buf[0] & 0x01; - hw->right = buf[0] & 0x02; + if (SYN_CAP_CLICKPAD(priv->ext_cap)) { + int click = (buf[0] ^ buf[3]) & 0x01; + + if (click && y < YMIN_NOMINAL) { + /* + * User pressed in ClickZone; report new button + * state but use old coordinates and don't report + * any pressure to prevent pointer movement. + */ + hw->left = x < CLICKPAD_LEFT_BTN_X; + hw->right = x > CLICKPAD_RIGHT_BTN_X; + hw->middle = x >= CLICKPAD_LEFT_BTN_X && + x <= CLICKPAD_RIGHT_BTN_X; + hw->z = 0; + + } else { + /* + * Finger is outside of the ClickZone - report + * current coordinates. + */ + hw->x = x; + hw->y = y; + + if (!click) + hw->left = hw->right = hw->middle = 0; + } + + } else { + hw->x = x; + hw->y = y; + + hw->left = buf[0] & 0x01; + hw->right = buf[0] & 0x02; - if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) { - hw->middle = (buf[0] ^ buf[3]) & 0x01; - hw->scroll = hw->w == 2 ? (signed char)(buf[1]) : 0; + if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) { + hw->middle = (buf[0] ^ buf[3]) & 0x01; + hw->scroll = hw->w == 2 ? (signed char)(buf[1]) : 0; + } } if (SYN_CAP_FOUR_BUTTON(priv->capabilities)) { @@ -476,8 +517,10 @@ static void synaptics_process_packet(struct psmouse *psmouse) input_report_key(dev, BTN_TOOL_TRIPLETAP, num_fingers == 3); } - if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) + if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities) || + SYN_CAP_CLICKPAD(priv->ext_cap)) { input_report_key(dev, BTN_MIDDLE, hw.middle); + } if (SYN_CAP_FOUR_BUTTON(priv->capabilities)) { input_report_key(dev, BTN_FORWARD, hw.up); diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h index 838e7f2..35360a6 100644 --- a/drivers/input/mouse/synaptics.h +++ b/drivers/input/mouse/synaptics.h @@ -48,6 +48,8 @@ #define SYN_CAP_VALID(c) ((((c) & 0x00ff00) >> 8) == 0x47) #define SYN_EXT_CAP_REQUESTS(c) (((c) & 0x700000) >> 20) #define SYN_CAP_MULTI_BUTTON_NO(ec) (((ec) & 0x00f000) >> 12) +#define SYN_CAP_PRODUCT_ID(ec) (((ec) & 0xff0000) >> 16) +#define SYN_CAP_CLICKPAD(ec) (SYN_CAP_PRODUCT_ID(ec) == 0xe4) /* synaptics modes query bits */ #define SYN_MODE_ABSOLUTE(m) ((m) & (1 << 7))