Hi Joshua,

this patch breaks ubcmtp on the MacBook Pro 8.2.  There is no problem
with the padding, but the pressure value is always 0, and wsmouse
doesn't register any touches.  I believe only type4 models fill the
'pressure' field.  At least for now, it's better to use the width
value (touch_major) as substitute for pressure (hidmt already does
this).  In case we add to wsmouse or wstpad some mechanism for palm/
thumb detection based on thresholds, this would work as well.
So I would prefer:
+               sc->frame[contacts].pressure =
+                   (int16_t)letoh16(finger->touch_major);

Moreover, it shouldn't be necessary to set the PRESSURE_LO/PRESSURE_HI
parameters in ubcmtp.  Only touchpads that are too sensitive need
them (if they are set, wsmouse ignores touches with lower pressure).

ok bru@ for the padding part

On 08/16/2018 04:51 AM, joshua stein wrote:
> Type 4 devices like the MacBookPro12,1 have extra padding in between 
> each chunk of finger data that needs to be skipped, otherwise the 
> offset will be wrong and each additional finger will read as static 
> coordinates.  This must have been overlooked when it was added to 
> the driver in 2015 since the first finger of data always read 
> properly.
> 
> Also, we can now pass in the actual pressure data instead of having 
> to use a constant value just to make the synaptics driver happy 
> since we now have wstpad.  The per-type min/max pressure values can 
> also be passed in when calling wsmouse_configure.
> 
> Tested on the 2015 MacBook Pro.  Tests on other Apple devices would 
> be appreciated.
> 
> 
> Index: sys/dev/usb/ubcmtp.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/usb/ubcmtp.c,v
> retrieving revision 1.18
> diff -u -p -u -p -r1.18 ubcmtp.c
> --- sys/dev/usb/ubcmtp.c      30 Jul 2018 15:56:30 -0000      1.18
> +++ sys/dev/usb/ubcmtp.c      16 Aug 2018 02:42:11 -0000
> @@ -118,6 +118,7 @@ struct ubcmtp_finger {
>  #define UBCMTP_TYPE4_TPLEN   UBCMTP_TYPE4_TPOFF + UBCMTP_ALL_FINGER_SIZE
>  #define UBCMTP_TYPE4_TPIFACE 2
>  #define UBCMTP_TYPE4_BTOFF   31
> +#define UBCMTP_TYPE4_FINGERPAD       (1 * sizeof(uint16_t))
>  
>  #define UBCMTP_FINGER_ORIENT 16384
>  #define UBCMTP_SN_PRESSURE   45
> @@ -128,9 +129,6 @@ struct ubcmtp_finger {
>  /* Identify clickpads in ubcmtp_configure. */
>  #define IS_CLICKPAD(ubcmtp_type) (ubcmtp_type != UBCMTP_TYPE1)
>  
> -/* Use a constant, synaptics-compatible pressure value for now. */
> -#define DEFAULT_PRESSURE     40
> -
>  struct ubcmtp_limit {
>       int limit;
>       int min;
> @@ -337,6 +335,7 @@ struct ubcmtp_softc {
>       int                     sc_tp_epaddr;   /* endpoint addr */
>       int                     tp_maxlen;      /* max size of tp data */
>       int                     tp_offset;      /* finger offset into data */
> +     int                     tp_fingerpad;   /* padding between finger data 
> */
>       uint8_t                 *tp_pkt;
>  
>       int                     bt_ifacenum;    /* button interface number */
> @@ -425,6 +424,7 @@ ubcmtp_attach(struct device *parent, str
>  
>       sc->sc_udev = uaa->device;
>       sc->sc_status = 0;
> +     sc->tp_fingerpad = 0;
>  
>       if ((udd = usbd_get_device_descriptor(dev)) == NULL) {
>               printf("ubcmtp: failed getting device descriptor\n");
> @@ -478,6 +478,7 @@ ubcmtp_attach(struct device *parent, str
>               sc->tp_maxlen = UBCMTP_TYPE4_TPLEN;
>               sc->tp_offset = UBCMTP_TYPE4_TPOFF;
>               sc->tp_ifacenum = UBCMTP_TYPE4_TPIFACE;
> +             sc->tp_fingerpad = UBCMTP_TYPE4_FINGERPAD;
>               break;
>       }
>  
> @@ -520,6 +521,10 @@ int
>  ubcmtp_configure(struct ubcmtp_softc *sc)
>  {
>       struct wsmousehw *hw = wsmouse_get_hw(sc->sc_wsmousedev);
> +     struct wsmouse_param params[] = {
> +             { WSMOUSECFG_PRESSURE_LO, sc->dev_type->l_pressure.min },
> +             { WSMOUSECFG_PRESSURE_HI, sc->dev_type->l_pressure.max },
> +     };
>  
>       hw->type = WSMOUSE_TYPE_TOUCHPAD;
>       hw->hw_type = (IS_CLICKPAD(sc->dev_type->type)
> @@ -531,7 +536,7 @@ ubcmtp_configure(struct ubcmtp_softc *sc
>       hw->mt_slots = UBCMTP_MAX_FINGERS;
>       hw->flags = WSMOUSEHW_MT_TRACKING;
>  
> -     return wsmouse_configure(sc->sc_wsmousedev, NULL, 0);
> +     return wsmouse_configure(sc->sc_wsmousedev, params, 0);
>  }
>  
>  int
> @@ -793,9 +798,9 @@ void
>  ubcmtp_tp_intr(struct usbd_xfer *xfer, void *priv, usbd_status status)
>  {
>       struct ubcmtp_softc *sc = priv;
> -     struct ubcmtp_finger *pkt;
> +     struct ubcmtp_finger *finger;
>       u_int32_t pktlen;
> -     int i, s, btn, contacts, fingers;
> +     int off, s, btn, contacts = 0;
>  
>       if (usbd_is_dying(sc->sc_udev) || !(sc->sc_status & UBCMTP_ENABLED))
>               return;
> @@ -816,16 +821,19 @@ ubcmtp_tp_intr(struct usbd_xfer *xfer, v
>       if (sc->tp_pkt == NULL || pktlen < sc->tp_offset)
>               return;
>  
> -     pkt = (struct ubcmtp_finger *)(sc->tp_pkt + sc->tp_offset);
> -     fingers = (pktlen - sc->tp_offset) / sizeof(struct ubcmtp_finger);
> -
>       contacts = 0;
> -     for (i = 0; i < fingers; i++) {
> -             if ((int16_t)letoh16(pkt[i].touch_major) == 0)
> +     for (off = sc->tp_offset; off < pktlen;
> +         off += (sizeof(struct ubcmtp_finger) + sc->tp_fingerpad)) {
> +             finger = (struct ubcmtp_finger *)(sc->tp_pkt + off);
> +
> +             if ((int16_t)letoh16(finger->touch_major) == 0)
>                       continue; /* finger lifted */
> -             sc->frame[contacts].x = (int16_t)letoh16(pkt[i].abs_x);
> -             sc->frame[contacts].y = (int16_t)letoh16(pkt[i].abs_y);
> -             sc->frame[contacts].pressure = DEFAULT_PRESSURE;
> +
> +             sc->frame[contacts].x = (int16_t)letoh16(finger->abs_x);
> +             sc->frame[contacts].y = (int16_t)letoh16(finger->abs_y);
> +             sc->frame[contacts].pressure =
> +                 (int16_t)letoh16(finger->pressure);
> +
>               contacts++;
>       }
>  
> 
> 

Reply via email to