[Applied] [PATCH] UBUNTU: (pre-stable): input: Support Clickpad devices in ClickZone mode
Brad Figg
brad.figg at canonical.com
Thu Dec 16 05:32:22 UTC 2010
On 12/14/2010 02:06 PM, Robert Hooker wrote:
> From: Takashi Iwai<tiwai at suse.de>
>
> 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<tiwai at suse.de>
>
> BugLink: http://bugs.launchpad.net/bugs/516329
>
> Acked-by: Colin King<colin.king at canonical.com>
> Acked-by: Andy Whitcroft<apw at canonical.com>
> Signed-off-by: Chase Douglas<chase.douglas at canonical.com>
> Signed-off-by: Andy Whitcroft<apw at canonical.com>
>
> Fixed clickpad capability checks to only check the 0x0c cap.
>
> Signed-off-by: Robert Hooker<robert.hooker at canonical.com>
> ---
> 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);
Applied and pushed to Maverick master-next.
--
Brad Figg brad.figg at canonical.com http://www.canonical.com
More information about the kernel-team
mailing list