From patchwork Fri Oct 8 17:48:39 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Takashi Iwai X-Patchwork-Id: 241981 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id o98Hmh3q030045 for ; Fri, 8 Oct 2010 17:48:53 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1759262Ab0JHRsl (ORCPT ); Fri, 8 Oct 2010 13:48:41 -0400 Received: from cantor.suse.de ([195.135.220.2]:33421 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1759186Ab0JHRsl (ORCPT ); Fri, 8 Oct 2010 13:48:41 -0400 Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.221.2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.suse.de (Postfix) with ESMTP id B62108E8CC; Fri, 8 Oct 2010 19:48:39 +0200 (CEST) Date: Fri, 08 Oct 2010 19:48:39 +0200 Message-ID: From: Takashi Iwai To: Chase Douglas Cc: linux-input@vger.kernel.org, xorg-devel@lists.x.org, Dmitry Torokhov , Chris Bagwell , Andy Whitcroft , Henrik Rydberg , linux-kernel@vger.kernel.org, Peter Hutterer , Duncan McGreggor Subject: Re: [PATCH 0/3] Input: synaptics - multitouch and multifinger support In-Reply-To: References: <1286549880-32580-1-git-send-email-chase.douglas@canonical.com> User-Agent: Wanderlust/2.15.6 (Almost Unreal) SEMI/1.14.6 (Maruoka) FLIM/1.14.9 (=?UTF-8?B?R29qxY0=?=) APEL/10.7 Emacs/23.1 (x86_64-suse-linux-gnu) MULE/6.0 (HANACHIRUSATO) MIME-Version: 1.0 (generated by SEMI 1.14.6 - "Maruoka") Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Fri, 08 Oct 2010 17:48:56 +0000 (UTC) --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -482,10 +482,88 @@ } #ifdef CONFIG_MOUSE_PS2_SYNAPTICS_MULTI_TOUCH -#define is_multi_touch(priv) (priv)->can_multi_touch +static int multi_touch_flag; + +static void setup_multi_touch(struct psmouse *psmouse, int verbose); + +static struct psmouse *_psmouse; + +static int param_set_multi_touch(const char *val, const struct kernel_param *kp) +{ + int mode, mode_changed; + + if (!val) + return -EINVAL; + mode = simple_strtol(val, NULL, 0); + if (mode < 0 || mode > 2) + return -EINVAL; + mode_changed = mode != multi_touch_flag; + multi_touch_flag = mode; + if (mode_changed) + setup_multi_touch(_psmouse, 1); + return 0; +} + +#define param_check_multi_touch(name, p) __param_check(name, p, int) + +static struct kernel_param_ops param_ops_multi_touch = { + .set = param_set_multi_touch, + .get = param_get_int, +}; + +module_param_named(multi_touch, multi_touch_flag, multi_touch, 0644); + +static inline int is_multi_touch(struct synaptics_data *priv) +{ + return (multi_touch_flag == 2 || + (priv->can_multi_touch && multi_touch_flag)); +} + +static void setup_multi_touch(struct psmouse *psmouse, int verbose) +{ + struct input_dev *dev; + struct synaptics_data *priv; + + _psmouse = psmouse; + if (!psmouse) + return; + dev = psmouse->dev; + priv = psmouse->private; + if (!dev || !priv) + return; + if (is_multi_touch(priv) && + !synaptics_init_multi_touch(psmouse)) { + if (verbose) + printk(KERN_INFO "Synaptics: enabling multi-touch\n"); + if (!SYN_CAP_MULTIFINGER(priv->capabilities)) { + __set_bit(BTN_TOOL_DOUBLETAP, dev->keybit); + __set_bit(BTN_TOOL_TRIPLETAP, dev->keybit); + } + input_set_abs_params(dev, ABS_MT_POSITION_X, + XMIN_NOMINAL, XMAX_NOMINAL, 0, 0); + input_set_abs_params(dev, ABS_MT_POSITION_Y, + YMIN_NOMINAL, YMAX_NOMINAL, 0, 0); + input_set_abs_params(dev, ABS_MT_PRESSURE, 0, 255, 0, 0); + input_abs_set_res(dev, ABS_MT_POSITION_X, priv->x_res); + input_abs_set_res(dev, ABS_MT_POSITION_Y, priv->y_res); + } else { + if (verbose) + printk(KERN_INFO "Synaptics: disabling multi-touch\n"); + if (!SYN_CAP_MULTIFINGER(priv->capabilities)) { + __clear_bit(BTN_TOOL_DOUBLETAP, dev->keybit); + __clear_bit(BTN_TOOL_TRIPLETAP, dev->keybit); + } + __clear_bit(ABS_MT_POSITION_X, dev->absbit); + __clear_bit(ABS_MT_POSITION_Y, dev->absbit); + __clear_bit(ABS_MT_PRESSURE, dev->absbit); + } +} + #else #define is_multi_touch(priv) 0 +#define setup_multi_touch(ps, v) do { } while (0) #endif + /* the multi-touch packet contains w=2 (like pen) */ #define is_multi_touch_packet(priv, hw) \ (is_multi_touch(priv) && (hw)->w == 2) @@ -781,7 +859,7 @@ __set_bit(BTN_LEFT, dev->keybit); __set_bit(BTN_RIGHT, dev->keybit); - if (SYN_CAP_MULTIFINGER(priv->capabilities) || is_multi_touch(priv)) { + if (SYN_CAP_MULTIFINGER(priv->capabilities)) { __set_bit(BTN_TOOL_DOUBLETAP, dev->keybit); __set_bit(BTN_TOOL_TRIPLETAP, dev->keybit); } @@ -810,20 +888,11 @@ __clear_bit(BTN_RIGHT, dev->keybit); __clear_bit(BTN_MIDDLE, dev->keybit); } - - if (is_multi_touch(priv)) { - input_set_abs_params(dev, ABS_MT_POSITION_X, - XMIN_NOMINAL, XMAX_NOMINAL, 0, 0); - input_set_abs_params(dev, ABS_MT_POSITION_Y, - YMIN_NOMINAL, YMAX_NOMINAL, 0, 0); - input_set_abs_params(dev, ABS_MT_PRESSURE, 0, 255, 0, 0); - input_abs_set_res(dev, ABS_MT_POSITION_X, priv->x_res); - input_abs_set_res(dev, ABS_MT_POSITION_Y, priv->y_res); - } } static void synaptics_disconnect(struct psmouse *psmouse) { + setup_multi_touch(NULL, 0); synaptics_free_led(psmouse); synaptics_reset(psmouse); kfree(psmouse->private); @@ -857,8 +926,7 @@ } synaptics_sync_led(psmouse); - if (is_multi_touch(priv)) - synaptics_init_multi_touch(psmouse); + setup_multi_touch(psmouse, 0); return 0; } @@ -937,16 +1005,8 @@ if (synaptics_init_led(psmouse) < 0) goto init_fail; - if (priv->can_multi_touch) { - if (synaptics_init_multi_touch(psmouse)) { - printk(KERN_WARNING "Synaptics: " - "unable to initialize multi-touch\n"); - priv->can_multi_touch = 0; - } else - printk(KERN_INFO "Synaptics: multi-touch enabled\n"); - } - set_input_params(psmouse->dev, priv); + setup_multi_touch(psmouse, 0); /* * Encode touchpad model so that it can be used to set