FreeBSD Bugzilla – Attachment 188126 Details for
Bug 222667
[psm] HP EliteBook 9470m: Synaptics touchpad detected as Generic PS/2 Mouse
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
synaptics-identify-0x46.patch
psm.c.diff (text/plain), 10.09 KB, created by
Vladimir Kondratyev
on 2017-11-19 21:48:23 UTC
(
hide
)
Description:
synaptics-identify-0x46.patch
Filename:
MIME Type:
Creator:
Vladimir Kondratyev
Created:
2017-11-19 21:48:23 UTC
Size:
10.09 KB
patch
obsolete
>diff --git a/sys/dev/atkbdc/psm.c b/sys/dev/atkbdc/psm.c >index fc611e7c517..be8363c0600 100644 >--- a/sys/dev/atkbdc/psm.c >+++ b/sys/dev/atkbdc/psm.c >@@ -132,6 +132,14 @@ __FBSDID("$FreeBSD$"); > > #define PSMCPNP_DRIVER_NAME "psmcpnp" > >+struct psmcpnp_softc { >+ enum { >+ PSMCPNP_GENERIC, >+ PSMCPNP_FORCEPAD, >+ PSMCPNP_HPSYN81, >+ } type; /* Based on PnP ID */ >+}; >+ > /* input queue */ > #define PSM_BUFSIZE 960 > #define PSM_SMALLBUFSIZE 240 >@@ -167,6 +175,15 @@ typedef struct packetbuf { > #define PSM_PACKETQUEUE 128 > #endif > >+/* >+ * Typical bezel limits. Taken from 'Synaptics >+ * PS/2 TouchPad Interfacing Guide' p.3.2.3. >+ */ >+#define SYNAPTICS_DEFAULT_MAX_X 5472 >+#define SYNAPTICS_DEFAULT_MAX_Y 4448 >+#define SYNAPTICS_DEFAULT_MIN_X 1472 >+#define SYNAPTICS_DEFAULT_MIN_Y 1408 >+ > typedef struct synapticsinfo { > struct sysctl_ctx_list sysctl_ctx; > struct sysctl_oid *sysctl_tree; >@@ -416,6 +433,7 @@ struct psm_softc { /* Driver status information */ > int squelch; /* level to filter movement at low speed */ > int syncerrors; /* # of bytes discarded to synchronize */ > int pkterrors; /* # of packets failed during quaranteen. */ >+ int fpcount; /* forcePad valid packet counter */ > struct timeval inputtimeout; > struct timeval lastsoftintr; /* time of last soft interrupt */ > struct timeval lastinputerr; /* time last sync error happened */ >@@ -1088,7 +1106,7 @@ doopen(struct psm_softc *sc, int command_byte) > mouse_ext_command(sc->kbdc, 1); > get_mouse_status(sc->kbdc, stat, 0, 3); > if ((SYNAPTICS_VERSION_GE(sc->synhw, 7, 5) || >- stat[1] == 0x47) && >+ stat[1] == 0x46 || stat[1] == 0x47) && > stat[2] == 0x40) { > synaptics_set_mode(sc, synaptics_preferred_mode(sc)); > VLOG(5, (LOG_DEBUG, "psm%d: Synaptis Absolute Mode " >@@ -3183,7 +3201,7 @@ proc_synaptics(struct psm_softc *sc, packetbuf_t *pb, mousestatus_t *ms, > static int touchpad_buttons; > static int guest_buttons; > static finger_t f[PSM_FINGERS]; >- int w, id, nfingers, ewcode, extended_buttons; >+ int w, id, nfingers, ewcode, extended_buttons, clickpad_pressed; > > extended_buttons = 0; > >@@ -3445,10 +3463,6 @@ proc_synaptics(struct psm_softc *sc, packetbuf_t *pb, mousestatus_t *ms, > extended_buttons |= sc->extended_buttons; > } > } >- /* Handle ClickPad */ >- if (sc->synhw.capClickPad && >- ((pb->ipacket[0] ^ pb->ipacket[3]) & 0x01)) >- touchpad_buttons |= MOUSE_BUTTON1DOWN; > > if (sc->synhw.capReportsV && nfingers > 1) > f[0] = (finger_t) { >@@ -3481,6 +3495,36 @@ proc_synaptics(struct psm_softc *sc, packetbuf_t *pb, mousestatus_t *ms, > if (f[0].p < sc->syninfo.min_pressure || f[0].x < 2) > nfingers = 0; > >+ /* Handle ClickPad */ >+ if (sc->synhw.capClickPad) { >+ clickpad_pressed = (pb->ipacket[0] ^ pb->ipacket[3]) & 0x01; >+ if (sc->synhw.forcePad) { >+ /* >+ * Forcepads erroneously report button click if there >+ * are 2 or more fingers on the touchpad breaking >+ * multifinger gestures. To workaround this start >+ * reporting a click only after 4 consecutive single >+ * touch packets has been received. >+ * Skip these packets in case more contacts appear. >+ */ >+ switch (nfingers) { >+ case 0: >+ sc->fpcount = 0; >+ break; >+ case 1: >+ if (clickpad_pressed && sc->fpcount < INT_MAX) >+ ++sc->fpcount; >+ /* FALLTHROUGH */ >+ default: >+ if (!clickpad_pressed) >+ sc->fpcount = 0; >+ if (sc->fpcount >= sc->syninfo.window_min) >+ touchpad_buttons |= MOUSE_BUTTON1DOWN; >+ } >+ } else if (clickpad_pressed) >+ touchpad_buttons |= MOUSE_BUTTON1DOWN; >+ } >+ > for (id = 0; id < PSM_FINGERS; id++) > if (id >= nfingers) > PSM_FINGER_RESET(f[id]); >@@ -6004,10 +6048,12 @@ synaptics_set_mode(struct psm_softc *sc, int mode_byte) { > static int > enable_synaptics(struct psm_softc *sc, enum probearg arg) > { >+ device_t psmcpnp; >+ struct psmcpnp_softc *psmcpnp_sc; > KBDC kbdc = sc->kbdc; > synapticshw_t synhw; > int status[3]; >- int buttons; >+ int buttons, middle_byte; > > VLOG(3, (LOG_DEBUG, "synaptics: BEGIN init\n")); > >@@ -6024,7 +6070,8 @@ enable_synaptics(struct psm_softc *sc, enum probearg arg) > return (FALSE); > if (get_mouse_status(kbdc, status, 0, 3) != 3) > return (FALSE); >- if (status[1] != 0x47) >+ middle_byte = status[1]; >+ if (middle_byte != 0x46 && middle_byte != 0x47) > return (FALSE); > > bzero(&synhw, sizeof(synhw)); >@@ -6035,7 +6082,15 @@ enable_synaptics(struct psm_softc *sc, enum probearg arg) > printf("Synaptics Touchpad v%d.%d\n", synhw.infoMajor, > synhw.infoMinor); > >- if (synhw.infoMajor < 4) { >+ /* >+ * Most synaptics touchpads return 0x47 in middle byte in responce to >+ * identify command as stated in p.4.4 of "Synaptics PS/2 TouchPad >+ * Interfacing Guide" and we only support v4.0 or better. But some >+ * devices return 0x46 here and have a different numbering scheme. >+ * In the case of 0x46, we allow versions as low as v2.0 >+ */ >+ if ((middle_byte == 0x47 && synhw.infoMajor < 4) || >+ (middle_byte == 0x46 && synhw.infoMajor < 2)) { > printf(" Unsupported (pre-v4) Touchpad detected\n"); > return (FALSE); > } >@@ -6076,15 +6131,38 @@ enable_synaptics(struct psm_softc *sc, enum probearg arg) > return (FALSE); > if (get_mouse_status(kbdc, status, 0, 3) != 3) > return (FALSE); >- if (!SYNAPTICS_VERSION_GE(synhw, 7, 5) && status[1] != 0x47) { >+ if (!SYNAPTICS_VERSION_GE(synhw, 7, 5) && status[1] != middle_byte) { > printf(" Failed to read extended capability bits\n"); > return (FALSE); > } > >+ psmcpnp = devclass_get_device(devclass_find(PSMCPNP_DRIVER_NAME), >+ sc->unit); >+ psmcpnp_sc = (psmcpnp != NULL) ? device_get_softc(psmcpnp) : NULL; >+ >+ /* >+ * Set conservative defaults for 0x46 middle byte touchpads >+ * as ExtendedQueries return bogus data. >+ */ >+ if (middle_byte == 0x46) { >+ synhw.capExtended = 1; >+ synhw.capPalmDetect = 1; >+ synhw.capPassthrough = 1; >+ synhw.capMultiFinger = 1; >+ synhw.maximumXCoord = SYNAPTICS_DEFAULT_MAX_X; >+ synhw.maximumYCoord = SYNAPTICS_DEFAULT_MAX_Y; >+ synhw.minimumXCoord = SYNAPTICS_DEFAULT_MIN_X; >+ synhw.minimumYCoord = SYNAPTICS_DEFAULT_MIN_Y; >+ /* Enable multitouch mode for HW v8.1 devices */ >+ if (psmcpnp_sc != NULL && >+ psmcpnp_sc->type == PSMCPNP_HPSYN81) >+ synhw.capReportsV = 1; >+ } else >+ synhw.capExtended = (status[0] & 0x80) != 0; >+ > /* Set the different capabilities when they exist. */ > buttons = 0; >- synhw.capExtended = (status[0] & 0x80) != 0; >- if (synhw.capExtended) { >+ if (synhw.capExtended && middle_byte == 0x47) { > synhw.nExtendedQueries = (status[0] & 0x70) >> 4; > synhw.capMiddle = (status[0] & 0x04) != 0; > synhw.capPassthrough = (status[2] & 0x80) != 0; >@@ -6206,12 +6284,8 @@ enable_synaptics(struct psm_softc *sc, enum probearg arg) > synhw.maximumYCoord = (status[2] << 5) | > ((status[1] & 0xf0) >> 3); > } else { >- /* >- * Typical bezel limits. Taken from 'Synaptics >- * PS/2 * TouchPad Interfacing Guide' p.3.2.3. >- */ >- synhw.maximumXCoord = 5472; >- synhw.maximumYCoord = 4448; >+ synhw.maximumXCoord = SYNAPTICS_DEFAULT_MAX_X; >+ synhw.maximumYCoord = SYNAPTICS_DEFAULT_MAX_Y; > } > > if (synhw.capReportsMin) { >@@ -6227,12 +6301,22 @@ enable_synaptics(struct psm_softc *sc, enum probearg arg) > synhw.minimumYCoord = (status[2] << 5) | > ((status[1] & 0xf0) >> 3); > } else { >- /* >- * Typical bezel limits. Taken from 'Synaptics >- * PS/2 * TouchPad Interfacing Guide' p.3.2.3. >- */ >- synhw.minimumXCoord = 1472; >- synhw.minimumYCoord = 1408; >+ synhw.minimumXCoord = SYNAPTICS_DEFAULT_MIN_X; >+ synhw.minimumYCoord = SYNAPTICS_DEFAULT_MIN_Y; >+ } >+ >+ /* >+ * ClickPad properties are not exported through PS/2 >+ * protocol. Detection is based on controller's PnP ID. >+ */ >+ if (synhw.capClickPad && psmcpnp_sc != NULL) { >+ switch (psmcpnp_sc->type) { >+ case PSMCPNP_FORCEPAD: >+ synhw.forcePad = 1; >+ break; >+ default: >+ break; >+ } > } > > if (verbose >= 2) { >@@ -6271,6 +6355,10 @@ enable_synaptics(struct psm_softc *sc, enum probearg arg) > printf(" minimumYCoord: %d\n", > synhw.minimumYCoord); > } >+ if (synhw.capClickPad) { >+ printf(" forcePad: %d\n", >+ synhw.forcePad); >+ } > } > buttons += synhw.capClickPad; > } >@@ -6300,7 +6388,7 @@ enable_synaptics(struct psm_softc *sc, enum probearg arg) > return (FALSE); > if (get_mouse_status(kbdc, status, 0, 3) != 3) > return (FALSE); >- if (!SYNAPTICS_VERSION_GE(synhw, 7, 5) && status[1] != 0x47) { >+ if (!SYNAPTICS_VERSION_GE(synhw, 7, 5) && status[1] != middle_byte) { > printf(" Failed to read mode byte\n"); > return (FALSE); > } >@@ -7096,7 +7184,7 @@ static device_method_t psmcpnp_methods[] = { > static driver_t psmcpnp_driver = { > PSMCPNP_DRIVER_NAME, > psmcpnp_methods, >- 1, /* no softc */ >+ sizeof(struct psmcpnp_softc), > }; > > static struct isa_pnp_id psmcpnp_ids[] = { >@@ -7116,6 +7204,18 @@ static struct isa_pnp_id psmcpnp_ids[] = { > { 0 } > }; > >+static struct isa_pnp_id forcepad_ids[] = { >+ { 0x0d302e4f, "HP PS/2 forcepad port" }, /* SYN300D, EB 1040 */ >+ { 0x14302e4f, "HP PS/2 forcepad port" }, /* SYN3014, EB 1040 */ >+ { 0 } >+}; >+ >+/* List of HW v8.1 synaptics touchpads erroneously detected as HW v2.0 */ >+static struct isa_pnp_id hpsyn81_ids[] = { >+ { 0x9e012e4f, "HP PS/2 trackpad port" }, /* SYN019E, EB 9470 */ >+ { 0 } >+}; >+ > static int > create_a_copy(device_t atkbdc, device_t me) > { >@@ -7142,11 +7242,18 @@ create_a_copy(device_t atkbdc, device_t me) > static int > psmcpnp_probe(device_t dev) > { >+ struct psmcpnp_softc *sc = device_get_softc(dev); > struct resource *res; > u_long irq; > int rid; > >- if (ISA_PNP_PROBE(device_get_parent(dev), dev, psmcpnp_ids)) >+ if (ISA_PNP_PROBE(device_get_parent(dev), dev, forcepad_ids) == 0) >+ sc->type = PSMCPNP_FORCEPAD; >+ else if(ISA_PNP_PROBE(device_get_parent(dev), dev, hpsyn81_ids) == 0) >+ sc->type = PSMCPNP_HPSYN81; >+ else if (ISA_PNP_PROBE(device_get_parent(dev), dev, psmcpnp_ids) == 0) >+ sc->type = PSMCPNP_GENERIC; >+ else > return (ENXIO); > > /* >diff --git a/sys/sys/mouse.h b/sys/sys/mouse.h >index 9fd1d6d8c08..42e57ebfe6c 100644 >--- a/sys/sys/mouse.h >+++ b/sys/sys/mouse.h >@@ -135,6 +135,7 @@ typedef struct synapticshw { > int maximumYCoord; > int infoXupmm; > int infoYupmm; >+ int forcePad; > } synapticshw_t; > > /* iftype */
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 222667
:
186785
|
187151
|
187245
|
187246
|
187251
|
187252
|
187253
|
187255
|
187284
|
187503
|
187547
|
187790
| 188126