lkml.org 
[lkml]   [2016]   [Feb]   [2]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: [PATCH] psmouse: added BYD touchpad driver
    Hi Richard,

    > This adds proper single-touch support for BYD touchpads to the psmouse input
    > driver.

    I posted a driver for the same touchpad a few weeks ago, which has been merged
    into linux-next. There's some stuff in this patch which is missing in my driver
    though, so we should definitely try and include that, and I'm very curious
    about the pseudo-absolute mode.

    > This patch is against commit b82dde0230439215b55e545880e90337ee16f51a (Merge tag
    > 'please-pull-copy_file_range' of
    > git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux ) of Linus' kernel
    > branch.

    Can you rebase against
    'git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input'?

    > +/* BYD commands reverse engineered from windows driver */
    > +
    > +/*
    > + * swipe gesture from off-pad to on-pad
    > + * 0 : disable
    > + * 1 : enable
    > + */
    > +#define BYD_CMD_SET_OFFSCREEN_SWIPE 0xcc
    > +/*
    > + * tap and drag delay time
    > + * 0 : disable
    > + * 1 - 8 : least to most delay
    > + */
    > +#define BYD_CMD_SET_TAP_DRAG_DELAY_TIME 0xcf
    > +/*
    > + * physical buttons function mapping
    > + * 0 : enable
    > + * 4 : normal
    > + * 5 : left button custom command
    > + * 6 : right button custom command
    > + * 8 : disable
    > + */
    > +#define BYD_CMD_SET_PHYSICAL_BUTTONS 0xd0
    > +/*
    > + * absolute mode (1 byte X/Y resolution)
    > + * 0 : disable
    > + * 2 : enable
    > + */
    > +#define BYD_CMD_SET_ABSOLUTE_MODE 0xd1
    > +/*
    > + * two finger scrolling
    > + * 1 : vertical
    > + * 2 : horizontal
    > + * 3 : vertical + horizontal
    > + * 4 : disable
    > + */
    > +#define BYD_CMD_SET_TWO_FINGER_SCROLL 0xd2
    > +/*
    > + * handedness
    > + * 1 : right handed
    > + * 2 : left handed
    > + */
    > +#define BYD_CMD_SET_HANDEDNESS 0xd3
    > +/*
    > + * tap to click
    > + * 1 : enable
    > + * 2 : disable
    > + */
    > +#define BYD_CMD_SET_TAP 0xd4
    > +/*
    > + * tap and drag
    > + * 1 : tap and hold to drag
    > + * 2 : tap and hold to drag + lock
    > + * 3 : disable
    > + */
    > +#define BYD_CMD_SET_TAP_DRAG 0xd5
    > +/*
    > + * touch sensitivity
    > + * 1 - 7 : least to most sensitive
    > + */
    > +#define BYD_CMD_SET_TOUCH_SENSITIVITY 0xd6
    > +/*
    > + * one finger scrolling
    > + * 1 : vertical
    > + * 2 : horizontal
    > + * 3 : vertical + horizontal
    > + * 4 : disable
    > + */
    > +#define BYD_CMD_SET_ONE_FINGER_SCROLL 0xd7
    > +/*
    > + * one finger scrolling function
    > + * 1 : free scrolling
    > + * 2 : edge motion
    > + * 3 : free scrolling + edge motion
    > + * 4 : disable
    > + */
    > +#define BYD_CMD_SET_ONE_FINGER_SCROLL_FUNC 0xd8
    > +/*
    > + * sliding speed
    > + * 1 - 5 : slowest to fastest
    > + */
    > +#define BYD_CMD_SET_SLIDING_SPEED 0xda
    > +/*
    > + * edge motion
    > + * 1 : disable
    > + * 2 : enable when dragging
    > + * 3 : enable when dragging and pointing
    > + */
    > +#define BYD_CMD_SET_EDGE_MOTION 0xdb
    > +/*
    > + * left edge region size
    > + * 0 - 7 : smallest to largest width
    > + */
    > +#define BYD_CMD_SET_LEFT_EDGE_REGION 0xdc
    > +/*
    > + * top edge region size
    > + * 0 - 9 : smallest to largest height
    > + */
    > +#define BYD_CMD_SET_TOP_EDGE_REGION 0xdd
    > +/*
    > + * disregard palm press as clicks
    > + * 1 - 6 : smallest to largest
    > + */
    > +#define BYD_CMD_SET_PALM_CHECK 0xde
    > +/* right edge region size
    > + * 0 - 7 : smallest to largest width
    > + */
    > +#define BYD_CMD_SET_RIGHT_EDGE_REGION 0xdf
    > +/*
    > + * bottom edge region size
    > + * 0 - 9 : smallest to largest height
    > + */
    > +#define BYD_CMD_SET_BOTTOM_EDGE_REGION 0xe1
    > +/*
    > + * multitouch gestures
    > + * 1 : enable
    > + * 2 : disable
    > + */
    > +#define BYD_CMD_SET_MULTITOUCH 0xe3
    > +/*
    > + * edge motion speed
    > + * 0 : control with finger pressure
    > + * 1 - 9 : slowest to fastest
    > + */
    > +#define BYD_CMD_SET_EDGE_MOTION_SPEED 0xe4
    > +/*
    > + * two finger scolling function
    > + * 0 : free scrolling
    > + * 1 : free scrolling (with momentum)
    > + * 2 : edge motion
    > + * 3 : free scrolling (with momentum) + edge motion
    > + * 4 : disable
    > + */
    > +#define BYD_CMD_SET_TWO_FINGER_SCROLL_FUNC 0xe5

    These are definitely worth merging into the existing driver - I never got the
    time to figure out all of the different settings.

    > +
    > +struct byd_data {
    > + struct timer_list timer;
    > + int32_t abs_x;
    > + int32_t abs_y;
    > + uint32_t last_touch_time;
    > + uint32_t button_left : 1;
    > + uint32_t button_right : 1;
    > + uint32_t touch : 1;
    > +};
    > +

    It looks like whatever email client you used has broken the formatting - when
    you resend, can you use something which will preserve whitespace properly? See
    'Documentation/email-clients.txt'.

    > +static void byd_report_input(struct psmouse *psmouse)
    > +{
    > + struct byd_data *priv = (struct byd_data *)psmouse->private;
    > + struct input_dev *dev = psmouse->dev;
    > +
    > + input_report_abs(dev, ABS_X, priv->abs_x);
    > + input_report_abs(dev, ABS_Y, priv->abs_y);
    > + input_report_key(dev, BTN_LEFT, priv->button_left);
    > + input_report_key(dev, BTN_RIGHT, priv->button_right);
    > + input_report_key(dev, BTN_TOUCH, priv->touch);
    > + input_report_key(dev, BTN_TOOL_FINGER, priv->touch);
    > +
    > + input_sync(dev);
    > +}

    Could you explain generally why you're reporting in absolute mode? What
    advantage does it have over using relative reporting and turning off the
    absolute packets in the touchpad init sequence?

    > +
    > +static void byd_clear_touch(unsigned long data)
    > +{
    > + struct psmouse *psmouse = (struct psmouse *)data;
    > + struct byd_data *priv = psmouse->private;
    > +
    > + serio_pause_rx(psmouse->ps2dev.serio);
    > +
    > + priv->touch = 0;
    > + /*
    > + * move cursor back to center of pad when we lose touch
    > + * this specifically improves user experiencce when moving
    > + * cursor with one finger, and pressing butoton with other
    > + */
    > + priv->abs_x = BYD_CONST_PAD_WIDTH / 2;
    > + priv->abs_y = BYD_CONST_PAD_HEIGHT / 2;
    > +
    > + byd_report_input(psmouse);

    serio_pause_rx() takes a spinlock - might be worth checking that
    byd_report_input() doesn't do anything that might sleep.

    > + switch (packet[3]) {
    > + case BYD_PKT_ABSOLUTE:
    > + /* on first touch, use the absolute packet to determine our start location */
    > + if (priv->touch == 0) {
    > + priv->abs_x = packet[1] * (BYD_CONST_PAD_WIDTH / 256);
    > + priv->abs_y = (255 - packet[2]) * (BYD_CONST_PAD_HEIGHT / 256);
    > +
    > + /* needed to detect tap */
    > + if (now_msecs - priv->last_touch_time > 64) {
    > + priv->touch = 1;
    > + }
    > + }
    > + break;
    > + case BYD_PKT_RELATIVE:
    > + {
    > + int32_t rel_x, rel_y;
    > +
    > + /* same as regular PS/2 psmouse protocoal */
    > + rel_x = packet[1] ? (int) packet[1] - (int) ((packet[0] << 4) & 0x100) : 0;
    > + rel_y = packet[2] ? (int) ((packet[0] << 3) & 0x100) - (int) packet[2] : 0;
    > +
    > + /*
    > + * experiments show relative mouse packets come in increments of
    > + * 1 unit / 11 msecs (regardless of time delta between relative packets)
    > + */
    > + priv->abs_x += rel_x * 11;
    > + priv->abs_y += rel_y * 11;
    > +
    > + priv->touch = 1;
    > + }

    So can this not handle gestures/multitouch?

    Cheers!
    Chris

    \
     
     \ /
      Last update: 2016-02-03 02:01    [W:4.129 / U:0.408 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site