Deleted Added
full compact
62c62
< __FBSDID("$FreeBSD: stable/11/sys/dev/atkbdc/psm.c 334763 2018-06-07 07:43:58Z hselasky $");
---
> __FBSDID("$FreeBSD: stable/11/sys/dev/atkbdc/psm.c 343158 2019-01-18 21:12:00Z wulf $");
139d138
< PSMCPNP_HPSYN81,
153a153,155
> /* Active PS/2 multiplexing */
> #define PSM_NOMUX (-1)
>
178,186d179
< /*
< * 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
<
450a444,448
> int muxport; /* MUX port with attached Synaptics */
> u_char muxsave[3]; /* 3->6 byte proto conversion buffer */
> int muxtpbuttons; /* Touchpad button state */
> int muxmsbuttons; /* Mouse (trackpoint) button state */
> struct timeval muxmidtimeout; /* middle button supression timeout */
615a614
> static int proc_synaptics_mux(struct psm_softc *, packetbuf_t *);
644a644
> static probefunc_t enable_synaptics_mux;
664a665,666
> { MOUSE_MODEL_SYNAPTICS, /* Synaptics Touchpad on Active Mux */
> 0x00, MOUSE_PS2_PACKETSIZE, enable_synaptics_mux },
1091a1094
> int mux_enabled = FALSE;
1105a1109,1117
> if (sc->muxport != PSM_NOMUX) {
> mux_enabled = enable_aux_mux(sc->kbdc) >= 0;
> if (mux_enabled)
> set_active_aux_mux_port(sc->kbdc, sc->muxport);
> else
> log(LOG_ERR, "psm%d: failed to enable "
> "active multiplexing mode.\n",
> sc->unit);
> }
1109c1121
< stat[1] == 0x46 || stat[1] == 0x47) &&
---
> stat[1] == 0x47) &&
1115a1128,1129
> if (mux_enabled)
> disable_aux_mux(sc->kbdc);
1363a1378
> sc->muxport = PSM_NOMUX;
1833c1848
< if (!error && sc->synhw.capPassthrough) {
---
> if (!error && (sc->synhw.capPassthrough || sc->muxport != PSM_NOMUX)) {
2952a2968,2970
> if (aux_mux_is_enabled(sc->kbdc))
> VLOG(2, (LOG_DEBUG, "psmintr: active multiplexing mode is not "
> "supported!\n"));
3304c3322
< if (sc->synhw.capPassthrough) {
---
> if (sc->synhw.capPassthrough || sc->muxport != PSM_NOMUX) {
3603a3622,3698
> proc_synaptics_mux(struct psm_softc *sc, packetbuf_t *pb)
> {
> int butt;
>
> /*
> * Convert 3-byte interleaved mixture of Synaptics and generic mouse
> * packets into plain 6-byte Synaptics packet protocol.
> * While in hidden multiplexing mode KBC does some editing of the
> * packet stream. It remembers the button bits from the last packet
> * received from each device, and replaces the button bits of every
> * packet with the logical OR of all devices��� most recent button bits.
> * This button crosstalk should be filtered out as Synaptics and
> * generic mouse encode middle button presses in a different way.
> */
> switch (pb->ipacket[0] & 0xc0) {
> case 0x80: /* First 3 bytes of Synaptics packet */
> bcopy(pb->ipacket, sc->muxsave, 3);
> /* Compute middle mouse button supression timeout. */
> sc->muxmidtimeout.tv_sec = 0;
> sc->muxmidtimeout.tv_usec = 50000; /* ~2-3 ints */
> timevaladd(&sc->muxmidtimeout, &sc->lastsoftintr);
> return (1);
>
> case 0xc0: /* Second 3 bytes of Synaptics packet */
> /* Join two 3-bytes absolute packets */
> bcopy(pb->ipacket, pb->ipacket + 3, 3);
> bcopy(sc->muxsave, pb->ipacket, 3);
> /* Prefer trackpoint buttons over touchpad's */
> pb->ipacket[0] &= ~(0x08 | sc->muxmsbuttons);
> pb->ipacket[3] &= ~(0x08 | sc->muxmsbuttons);
> butt = (pb->ipacket[3] & 0x03) << 2 | (pb->ipacket[0] & 0x03);
> /* Add hysteresis to remove spurious middle button events */
> if (butt != sc->muxtpbuttons && sc->fpcount < 1) {
> pb->ipacket[0] &= 0xfc;
> pb->ipacket[0] |= sc->muxtpbuttons & 0x03;
> pb->ipacket[3] &= 0xfc;
> pb->ipacket[3] |= sc->muxtpbuttons >> 2 & 0x03;
> ++sc->fpcount;
> } else {
> sc->fpcount = 0;
> sc->muxtpbuttons = butt;
> }
> /* Filter out impossible w induced by middle trackpoint btn */
> if (sc->synhw.capExtended && !sc->synhw.capPassthrough &&
> (pb->ipacket[0] & 0x34) == 0x04 &&
> (pb->ipacket[3] & 0x04) == 0x04) {
> pb->ipacket[0] &= 0xfb;
> pb->ipacket[3] &= 0xfb;
> }
> sc->muxsave[0] &= 0x30;
> break;
>
> default: /* Generic mouse (Trackpoint) packet */
> /* Filter out middle button events induced by some w values */
> if (sc->muxmsbuttons & 0x03 || pb->ipacket[0] & 0x03 ||
> (timevalcmp(&sc->lastsoftintr, &sc->muxmidtimeout, <=) &&
> (sc->muxsave[0] & 0x30 || sc->muxsave[2] > 8)))
> pb->ipacket[0] &= 0xfb;
> sc->muxmsbuttons = pb->ipacket[0] & 0x07;
> /* Convert to Synaptics pass-through protocol */
> pb->ipacket[4] = pb->ipacket[1];
> pb->ipacket[5] = pb->ipacket[2];
> pb->ipacket[1] = pb->ipacket[0];
> pb->ipacket[2] = 0;
> pb->ipacket[0] = 0x84 | (sc->muxtpbuttons & 0x03);
> pb->ipacket[3] = 0xc4 | (sc->muxtpbuttons >> 2 & 0x03);
> }
>
> VLOG(4, (LOG_DEBUG, "synaptics: %02x %02x %02x %02x %02x %02x\n",
> pb->ipacket[0], pb->ipacket[1], pb->ipacket[2],
> pb->ipacket[3], pb->ipacket[4], pb->ipacket[5]));
>
> pb->inputbytes = MOUSE_SYNAPTICS_PACKETSIZE;
> return (0);
> }
>
> static int
4937a5033,5036
> if (pb->inputbytes == MOUSE_PS2_PACKETSIZE)
> if (proc_synaptics_mux(sc, pb))
> goto next;
>
6047a6147,6151
> /*
> * AUX MUX detection code should be placed at very beginning of probe sequence
> * at least before 4-byte protocol mouse probes e.g. MS IntelliMouse probe as
> * latter can trigger switching the MUX to incompatible state.
> */
6048a6153,6201
> enable_synaptics_mux(struct psm_softc *sc, enum probearg arg)
> {
> KBDC kbdc = sc->kbdc;
> int port, version;
> int probe = FALSE;
> int active_ports_count = 0;
> int active_ports_mask = 0;
>
> version = enable_aux_mux(kbdc);
> if (version == -1)
> return (FALSE);
>
> for (port = 0; port < KBDC_AUX_MUX_NUM_PORTS; port++) {
> VLOG(3, (LOG_DEBUG, "aux_mux: ping port %d\n", port));
> set_active_aux_mux_port(kbdc, port);
> if (enable_aux_dev(kbdc) && disable_aux_dev(kbdc)) {
> active_ports_count++;
> active_ports_mask |= 1 << port;
> }
> }
>
> if (verbose >= 2)
> printf("Active Multiplexing PS/2 controller v%d.%d with %d "
> "active port(s)\n", version >> 4 & 0x0f, version & 0x0f,
> active_ports_count);
>
> /* psm has a special support for GenMouse + SynTouchpad combination */
> if (active_ports_count >= 2) {
> for (port = 0; port < KBDC_AUX_MUX_NUM_PORTS; port++) {
> if ((active_ports_mask & 1 << port) == 0)
> continue;
> 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) {
> if (arg == PROBE)
> sc->muxport = port;
> break;
> }
> }
> }
>
> /* IRQ handler does not support active multiplexing mode */
> disable_aux_mux(kbdc);
>
> return (probe);
> }
>
> static int
6056c6209
< int buttons, middle_byte;
---
> int buttons;
6073,6074c6226
< middle_byte = status[1];
< if (middle_byte != 0x46 && middle_byte != 0x47)
---
> if (status[1] != 0x47)
6085,6093c6237
< /*
< * 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)) {
---
> if (synhw.infoMajor < 4) {
6134c6278
< if (!SYNAPTICS_VERSION_GE(synhw, 7, 5) && status[1] != middle_byte) {
---
> if (!SYNAPTICS_VERSION_GE(synhw, 7, 5) && status[1] != 0x47) {
6143,6162d6286
< /*
< * 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;
<
6165c6289,6290
< if (synhw.capExtended && middle_byte == 0x47) {
---
> synhw.capExtended = (status[0] & 0x80) != 0;
> if (synhw.capExtended) {
6287,6288c6412,6417
< synhw.maximumXCoord = SYNAPTICS_DEFAULT_MAX_X;
< synhw.maximumYCoord = SYNAPTICS_DEFAULT_MAX_Y;
---
> /*
> * Typical bezel limits. Taken from 'Synaptics
> * PS/2 * TouchPad Interfacing Guide' p.3.2.3.
> */
> synhw.maximumXCoord = 5472;
> synhw.maximumYCoord = 4448;
6304,6305c6433,6438
< synhw.minimumXCoord = SYNAPTICS_DEFAULT_MIN_X;
< synhw.minimumYCoord = SYNAPTICS_DEFAULT_MIN_Y;
---
> /*
> * Typical bezel limits. Taken from 'Synaptics
> * PS/2 * TouchPad Interfacing Guide' p.3.2.3.
> */
> synhw.minimumXCoord = 1472;
> synhw.minimumYCoord = 1408;
6391c6524
< if (!SYNAPTICS_VERSION_GE(synhw, 7, 5) && status[1] != middle_byte) {
---
> if (!SYNAPTICS_VERSION_GE(synhw, 7, 5) && status[1] != 0x47) {
7214,7219d7346
< /* 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 }
< };
<
7253,7254d7379
< else if(ISA_PNP_PROBE(device_get_parent(dev), dev, hpsyn81_ids) == 0)
< sc->type = PSMCPNP_HPSYN81;