Re: [PATCH 2/2]input - wacom_w8001: Add one finger touch support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Dec 8, 2010 at 7:23 PM, Ping Cheng <pinglinux@xxxxxxxxx> wrote:
> Signed-off-by: Ping Cheng <pingc@xxxxxxxxx>
> ---
>  drivers/input/touchscreen/wacom_w8001.c |   74 +++++++++++++++++++++++++++++--
>  1 files changed, 70 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/input/touchscreen/wacom_w8001.c b/drivers/input/touchscreen/wacom_w8001.c
> index 90b92e8..68087d8 100644
> --- a/drivers/input/touchscreen/wacom_w8001.c
> +++ b/drivers/input/touchscreen/wacom_w8001.c
> @@ -3,6 +3,7 @@
>  *
>  * Copyright (c) 2008 Jaya Kumar
>  * Copyright (c) 2010 Red Hat, Inc.
> + * Copyright (c) 2010 Ping Cheng, Wacom. <pingc@xxxxxxxxx>
>  *
>  * This file is subject to the terms and conditions of the GNU General Public
>  * License. See the file COPYING in the main directory of this archive for
> @@ -86,6 +87,12 @@ struct w8001 {
>        char phys[32];
>        int type;
>        unsigned int pktlen;
> +       bool pen_in_prox;
> +       bool has_touch;
> +       int max_touch_x;
> +       int max_touch_y;
> +       int max_pen_x;
> +       int max_pen_y;
>  };
>
>  static void parse_data(u8 *data, struct w8001_coord *coord)
> @@ -112,6 +119,29 @@ static void parse_data(u8 *data, struct w8001_coord *coord)
>        coord->tilt_y = data[8] & 0x7F;
>  }
>
> +static void parse_single_touch(struct w8001 *w8001)
> +{
> +       struct input_dev *dev = w8001->dev;
> +       unsigned char *data = w8001->data;
> +
> +       int x = (data[1] << 7) | data[2];
> +       int y = (data[3] << 7) | data[4];
> +       w8001->has_touch = data[0] & 0x1;
> +
> +       /* scale to pen maximum */
> +       if (w8001->max_pen_x && w8001->max_pen_y && w8001->max_touch_x) {
> +               x = x * w8001->max_pen_x / w8001->max_touch_x;
> +               y = y * w8001->max_pen_y / w8001->max_touch_y;

Ok, you are doing scaling.

> +       }
> +
> +       input_report_abs(dev, ABS_X, x);
> +       input_report_abs(dev, ABS_Y, y);
> +       input_report_key(dev, BTN_TOUCH, w8001->has_touch);
> +       input_report_key(dev, BTN_TOOL_FINGER, w8001->has_touch);

Wacom seems good about report x/y=0 when !has_touch but its probably
safer to enforce that if this can be a combo device.  More below.

> +
> +       input_sync(dev);
> +}
> +
>  static void parse_touch(struct w8001 *w8001)
>  {
>        struct input_dev *dev = w8001->dev;
> @@ -151,6 +181,18 @@ static void parse_touchquery(u8 *data, struct w8001_touch_query *query)
>        query->y = data[5] << 9;
>        query->y |= data[6] << 2;
>        query->y |= (data[2] >> 3) & 0x3;
> +
> +       /* Early days' one finger touch models need the following defaults */
> +       if (!query->x && !query->y) {
> +               query->x = 1024;
> +               query->y = 1024;
> +               query->panel_res = 10;
> +               query->panel_res = 10;
> +               if (data[1]) {
> +                       query->x = (1 << data[1]);
> +                       query->y = (1 << data[1]);
> +               }
> +       }
>  }
>
>  static void report_pen_events(struct w8001 *w8001, struct w8001_coord *coord)
> @@ -199,6 +241,7 @@ static irqreturn_t w8001_interrupt(struct serio *serio,
>                                   unsigned char data, unsigned int flags)
>  {
>        struct w8001 *w8001 = serio_get_drvdata(serio);
> +       struct input_dev *dev = w8001->dev;
>        struct w8001_coord coord;
>        unsigned char tmp;
>
> @@ -213,9 +256,15 @@ static irqreturn_t w8001_interrupt(struct serio *serio,
>
>        case W8001_PKTLEN_TOUCH93 - 1:
>        case W8001_PKTLEN_TOUCH9A - 1:
> -               /* ignore one-finger touch packet. */
> -               if (w8001->pktlen == w8001->idx)
> +               tmp = (w8001->data[0] & W8001_TOUCH_BYTE);
> +               if (tmp != W8001_TOUCH_BYTE)
> +                       break;
> +
> +               if (w8001->pktlen == w8001->idx) {
>                        w8001->idx = 0;
> +                       if (!w8001->pen_in_prox)
> +                               parse_single_touch(w8001);
> +               }
>                break;
>
>        /* Pen coordinates packet */
> @@ -228,9 +277,17 @@ static irqreturn_t w8001_interrupt(struct serio *serio,
>                if (tmp == W8001_TOUCH_BYTE)
>                        break;
>
> +               if (w8001->has_touch) {
> +                       /* send touch data out */
> +                       w8001->has_touch = 0;
> +                       input_report_key(dev, BTN_TOUCH, 0);
> +                       input_report_key(dev, BTN_TOOL_FINGER, 0);

Probably its better to set ABS_X/ABS_Y to zero and do a sync here?  So
duplicate x/y values don't get dropped and aligns with wacom_wac.c.
This is related to comment about forcing ABS_X/Y to zero above.  Its
so pen has known starting point when coming in proximity.  I wouldn't
do one without the other.

Chris

> +               }
> +
>                w8001->idx = 0;
>                parse_data(w8001->data, &coord);
>                report_pen_events(w8001, &coord);
> +               w8001->pen_in_prox = coord.rdy ? true : false;
>                break;
>
>        /* control packet */
> @@ -313,11 +370,20 @@ static int w8001_setup(struct w8001 *w8001)
>         */
>        if (!error && w8001->response[1]) {
>                struct w8001_touch_query touch;
> +               int px, py;
>
>                parse_touchquery(w8001->response, &touch);
>
> -               input_set_abs_params(dev, ABS_X, 0, touch.x, 0, 0);
> -               input_set_abs_params(dev, ABS_Y, 0, touch.y, 0, 0);
> +               px = w8001->max_touch_x = touch.x;
> +               py = w8001->max_touch_x = touch.y;
> +
> +               /* scale to pen maximum */
> +               if (coord.x && coord.y) {
> +                       px = w8001->max_pen_x = coord.x;
> +                       py = w8001->max_pen_y = coord.y;
> +               }
> +               input_set_abs_params(dev, ABS_X, 0, px, 0, 0);
> +               input_set_abs_params(dev, ABS_Y, 0, py, 0, 0);

I see.  My previous comments are addressed... except for MT comment.
Should those be disabled or does sensor_id take care of that?

>                dev->keybit[BIT_WORD(BTN_TOOL_FINGER)] |= BIT_MASK(BTN_TOOL_FINGER);
>
>                switch (touch.sensor_id) {
> --
> 1.7.2.3
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-input" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media Devel]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Linux Wireless Networking]     [Linux Omap]

  Powered by Linux