FreeBSD Bugzilla – Attachment 197625 Details for
Bug 231058
no support for active PS/2 multiplexing results in erratic behaviour of Synaptics touchpad on HP 8560w
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
touchpad/trackpoint coexistence patch (draft)
aux_mux.patch (text/plain), 8.54 KB, created by
Vladimir Kondratyev
on 2018-09-30 11:17:00 UTC
(
hide
)
Description:
touchpad/trackpoint coexistence patch (draft)
Filename:
MIME Type:
Creator:
Vladimir Kondratyev
Created:
2018-09-30 11:17:00 UTC
Size:
8.54 KB
patch
obsolete
>diff --git a/sys/dev/atkbdc/atkbdc.c b/sys/dev/atkbdc/atkbdc.c >index b53de3ef299b..483886915e56 100644 >--- a/sys/dev/atkbdc/atkbdc.c >+++ b/sys/dev/atkbdc/atkbdc.c >@@ -296,6 +296,7 @@ atkbdc_setup(atkbdc_softc_t *sc, bus_space_tag_t tag, bus_space_handle_t h0, > sc->lock = FALSE; > sc->kbd.head = sc->kbd.tail = 0; > sc->aux.head = sc->aux.tail = 0; >+ sc->aux_mux_enabled = FALSE; > #if KBDIO_DEBUG >= 2 > sc->kbd.call_count = 0; > sc->kbd.qcount = sc->kbd.max_qcount = 0; >@@ -639,7 +640,12 @@ write_kbd_command(KBDC p, int c) > int > write_aux_command(KBDC p, int c) > { >- if (!write_controller_command(p, KBDC_WRITE_TO_AUX)) >+ int f; >+ >+ f = kbdcp(p)->aux_mux_enabled ? >+ KBDC_WRITE_TO_AUX_MUX + kbdcp(p)->aux_mux_port : KBDC_WRITE_TO_AUX; >+ >+ if (!write_controller_command(p, f)) > return FALSE; > return write_controller_data(p, c); > } >@@ -1201,3 +1207,69 @@ set_controller_command_byte(KBDC p, int mask, int command) > > return TRUE; > } >+ >+/* >+ * Rudimentary support for active PS/2 multiplexing >+ */ >+static int >+set_aux_mux_state(KBDC p, int enabled) >+{ >+ int command, version; >+ >+ if (write_controller_command(p, KBDC_FORCE_AUX_OUTPUT) == 0 || >+ write_controller_data(p, 0xF0) == 0 || >+ read_controller_data(p) != 0xF0) >+ return -1; >+ >+ if (write_controller_command(p, KBDC_FORCE_AUX_OUTPUT) == 0 || >+ write_controller_data(p, 0x56) == 0 || >+ read_controller_data(p) != 0x56) >+ return -1; >+ >+ command = enabled ? 0xa4 : 0xa5; >+ if (write_controller_command(p, KBDC_FORCE_AUX_OUTPUT) == 0 || >+ write_controller_data(p, command) == 0 || >+ (version = read_controller_data(p)) == command) >+ return -1; >+ >+ return version; >+} >+ >+int >+set_active_aux_mux_port(KBDC p, int port) >+{ >+ >+ if (!kbdcp(p)->aux_mux_enabled) >+ return FALSE; >+ >+ if (port < 0 || port >= KBDC_AUX_MUX_NUM_PORTS) >+ return FALSE; >+ >+ kbdcp(p)->aux_mux_port = port; >+ >+ return TRUE; >+} >+ >+/* Checks for active multiplexing support and enables it */ >+int >+enable_aux_mux(KBDC p) >+{ >+ int version; >+ >+ version = set_aux_mux_state(p, TRUE); >+ if (version >= 0) { >+ kbdcp(p)->aux_mux_enabled = TRUE; >+ set_active_aux_mux_port(p, 0); >+ } >+ >+ return version; >+} >+ >+int >+disable_aux_mux(KBDC p) >+{ >+ >+ kbdcp(p)->aux_mux_enabled = FALSE; >+ >+ return (set_aux_mux_state(p, FALSE)); >+} >diff --git a/sys/dev/atkbdc/atkbdcreg.h b/sys/dev/atkbdc/atkbdcreg.h >index 576dec967391..e320fecf6a3a 100644 >--- a/sys/dev/atkbdc/atkbdcreg.h >+++ b/sys/dev/atkbdc/atkbdcreg.h >@@ -51,6 +51,8 @@ > /* controller commands (sent to KBD_COMMAND_PORT) */ > #define KBDC_SET_COMMAND_BYTE 0x0060 > #define KBDC_GET_COMMAND_BYTE 0x0020 >+#define KBDC_WRITE_TO_AUX_MUX 0x0090 >+#define KBDC_FORCE_AUX_OUTPUT 0x00d3 > #define KBDC_WRITE_TO_AUX 0x00d4 > #define KBDC_DISABLE_AUX_PORT 0x00a7 > #define KBDC_ENABLE_AUX_PORT 0x00a8 >@@ -117,6 +119,8 @@ > #define KBDS_KBD_BUFFER_FULL 0x0001 > #define KBDS_AUX_BUFFER_FULL 0x0021 > #define KBDS_INPUT_BUFFER_FULL 0x0002 >+#define KBDS_AUX_MUX_ERROR 0x0004 >+#define KBDS_AUX_MUX_PORT 0x00c0 > > /* return code */ > #define KBD_ACK 0x00fa >@@ -209,6 +213,8 @@ typedef struct atkbdc_softc { > #define KBDC_QUIRK_IGNORE_PROBE_RESULT (1 << 1) > #define KBDC_QUIRK_RESET_AFTER_PROBE (1 << 2) > #define KBDC_QUIRK_SETLEDS_ON_INIT (1 << 3) >+ int aux_mux_enabled; /* active PS/2 multiplexing is enabled */ >+ int aux_mux_port; /* current aux mux port */ > } atkbdc_softc_t; > > enum kbdc_device_ivar { >@@ -223,6 +229,8 @@ typedef caddr_t KBDC; > #define KBDC_RID_KBD 0 > #define KBDC_RID_AUX 1 > >+#define KBDC_AUX_MUX_NUM_PORTS 4 >+ > /* function prototypes */ > > atkbdc_softc_t *atkbdc_get_softc(int unit); >@@ -268,6 +276,10 @@ void kbdc_set_device_mask(KBDC kbdc, int mask); > int get_controller_command_byte(KBDC kbdc); > int set_controller_command_byte(KBDC kbdc, int command, int flag); > >+int set_active_aux_mux_port(KBDC p, int port); >+int enable_aux_mux(KBDC p); >+int disable_aux_mux(KBDC p); >+ > #endif /* _KERNEL */ > > #endif /* !_DEV_ATKBDC_ATKBDCREG_H_ */ >diff --git a/sys/dev/atkbdc/psm.c b/sys/dev/atkbdc/psm.c >index 32c8e1d3d7fc..e782e9fdc18f 100644 >--- a/sys/dev/atkbdc/psm.c >+++ b/sys/dev/atkbdc/psm.c >@@ -499,6 +499,7 @@ static int verbose = PSM_DEBUG; > static int synaptics_support = 0; > static int trackpoint_support = 0; > static int elantech_support = 0; >+static int force_mux_discovery = 0; > > /* for backward compatibility */ > #define OLD_MOUSE_GETHWINFO _IOR('M', 1, old_mousehw_t) >@@ -642,6 +643,7 @@ static probefunc_t enable_4dmouse; > static probefunc_t enable_4dplus; > static probefunc_t enable_mmanplus; > static probefunc_t enable_synaptics; >+static probefunc_t enable_synaptics_mux; > static probefunc_t enable_trackpoint; > static probefunc_t enable_versapad; > static probefunc_t enable_elantech; >@@ -674,6 +676,8 @@ static struct { > 0x08, MOUSE_4D_PACKETSIZE, enable_4dmouse }, > { MOUSE_MODEL_4DPLUS, /* A4 Tech 4D+ Mouse */ > 0xc8, MOUSE_4DPLUS_PACKETSIZE, enable_4dplus }, >+ { MOUSE_MODEL_SYNAPTICS, /* Synaptics Touchpad on Active Mux */ >+ 0x00, MOUSE_PS2_PACKETSIZE, enable_synaptics_mux }, > { MOUSE_MODEL_SYNAPTICS, /* Synaptics Touchpad */ > 0xc0, MOUSE_SYNAPTICS_PACKETSIZE, enable_synaptics }, > { MOUSE_MODEL_ELANTECH, /* Elantech Touchpad */ >@@ -2933,6 +2937,9 @@ SYSCTL_INT(_hw_psm, OID_AUTO, trackpoint_support, CTLFLAG_RDTUN, > SYSCTL_INT(_hw_psm, OID_AUTO, elantech_support, CTLFLAG_RDTUN, > &elantech_support, 0, "Enable support for Elantech touchpads"); > >+SYSCTL_INT(_hw_psm, OID_AUTO, force_mux_discovery, CTLFLAG_RDTUN, >+ &force_mux_discovery, 0, "Force probing of multiplexed PS/2 ports"); >+ > static void > psmintr(void *arg) > { >@@ -2940,7 +2947,12 @@ psmintr(void *arg) > struct timeval now; > int c; > packetbuf_t *pb; >+ static int active_mode_logged = FALSE; > >+ if (kbdcp(sc->kbdc)->aux_mux_enabled && !active_mode_logged) { >+ printf ("psm0: AUX IRQ fired in active multiplexing mode"); >+ active_mode_logged = TRUE; >+ } > > /* read until there is nothing to read */ > while((c = read_aux_data_no_wait(sc->kbdc)) != -1) { >@@ -4933,6 +4945,30 @@ psmsoftintr(void *arg) > break; > > case MOUSE_MODEL_SYNAPTICS: >+ if (sc->mode.packetsize == 3) { >+ static u_char save[3]; >+ /* Don't rely on bit 3. It is garbled by mux */ >+ switch (pb->ipacket[0] & 0xc0) { >+ case 0x80: >+ bcopy(pb->ipacket, save, 3); >+ goto next; >+ case 0xc0: >+ /* Join two 3-bytes absolute packets */ >+ bcopy(pb->ipacket, pb->ipacket + 3, 3); >+ bcopy(save, pb->ipacket, 3); >+ save[0] &= 0x03; >+ break; >+ default: >+ /* Convert generic -> pass-through */ >+ pb->ipacket[5] = pb->ipacket[2]; >+ pb->ipacket[4] = pb->ipacket[1]; >+ pb->ipacket[1] = pb->ipacket[0]; >+ pb->ipacket[0] = 0x84 | (save[0] & 3); >+ pb->ipacket[3] = 0xc4 | (save[0] & 3); >+ pb->ipacket[2] = 0; >+ } >+ pb->inputbytes = 6; >+ } > if (proc_synaptics(sc, pb, &ms, &x, &y, &z) != 0) { > VLOG(3, (LOG_DEBUG, "synaptics: " > "packet rejected\n")); >@@ -6043,6 +6079,54 @@ synaptics_set_mode(struct psm_softc *sc, int mode_byte) { > } > } > >+static int >+enable_synaptics_mux(struct psm_softc *sc, enum probearg arg) >+{ >+ KBDC kbdc = sc->kbdc; >+ int status[3]; >+ int port, probe = FALSE, version, has_trackpoint = FALSE; >+ >+ /* >+ * Some HP laptops e.g. EB 8560w and 9470m have a trackpoint attached >+ * to AUX multiplexer rather than to synaptics pass-through interface. >+ * If active multiplexing mode is not activated this device produces >+ * own response to synaptics identify query thus preventing synaptics >+ * touchpad detection. >+ */ >+ set_mouse_scaling(kbdc, 1); >+ if (mouse_ext_command(kbdc, 0) && >+ get_mouse_status(kbdc, status, 0, 3) == 3 && >+ status[0] == 0x00 && status[1] == 0x46 && status[2] == 0x12) >+ has_trackpoint = TRUE; >+ >+ version = enable_aux_mux(kbdc); >+ if (version == -1) >+ return (FALSE); >+ >+ if (verbose >= 2) >+ printf("Active Multiplexing PS/2 controller v%d.%d\n", >+ (version >> 4) & 0x0f, version & 0x0f); >+ >+ /* If trackpoint is detected we should scan AUX ports in active mode */ >+ if (has_trackpoint || force_mux_discovery) { >+ for (port = 0; port < KBDC_AUX_MUX_NUM_PORTS; port++) { >+ VLOG(3, (LOG_DEBUG, "aux_mux: probe port %d\n", port)); >+ set_active_aux_mux_port(kbdc, port); >+ probe = enable_synaptics(sc, arg); >+ if (probe) { >+ /* Relative mouses are mapped to passthrough */ >+ sc->synhw.capPassthrough = 1; >+ break; >+ } >+ } >+ } >+ >+ /* Back to hidden multiplexing. Active one is not supported by reads */ >+ disable_aux_mux(kbdc); >+ >+ return (probe); >+} >+ > static int > enable_synaptics(struct psm_softc *sc, enum probearg arg) > {
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 231058
:
196747
|
197498
|
197499
|
197500
|
197560
|
197561
|
197562
|
197580
|
197603
|
197619
|
197625
|
197626
|
197637
|
197658
|
197703
|
197704
|
198030
|
198791
|
198807
|
198824
|
198852
|
198863
|
198878
|
198880
|
198898
|
198926
|
198934
|
199114
|
199294
|
199322
|
199327
|
199329