^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Synaptics TouchPad PS/2 mouse driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * 2003 Dmitry Torokhov <dtor@mail.ru>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Added support for pass-through port. Special thanks to Peter Berg Larsen
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * for explaining various Synaptics quirks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * 2003 Peter Osterlund <petero2@telia.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Ported to 2.5 input device infrastructure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Copyright (C) 2001 Stefan Gmeiner <riddlebox@freesurf.ch>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * start merging tpconfig and gpm code to a xfree-input module
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * adding some changes and extensions (ex. 3rd and 4th button)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * Copyright (c) 1997 C. Scott Ananian <cananian@alumni.priceton.edu>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * Copyright (c) 1998-2000 Bruce Kalk <kall@compass.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * code for the special synaptics commands (from the tpconfig-source)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * Trademarks are the property of their respective owners.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/dmi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/input/mt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/serio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/libps2.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/rmi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include "psmouse.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include "synaptics.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * The x/y limits are taken from the Synaptics TouchPad interfacing Guide,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * section 2.3.2, which says that they should be valid regardless of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * actual size of the sensor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * Note that newer firmware allows querying device for maximum useable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * coordinates.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define XMIN 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define XMAX 6143
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define YMIN 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define YMAX 6143
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define XMIN_NOMINAL 1472
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define XMAX_NOMINAL 5472
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define YMIN_NOMINAL 1408
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define YMAX_NOMINAL 4448
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /* Size in bits of absolute position values reported by the hardware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define ABS_POS_BITS 13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * These values should represent the absolute maximum value that will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * be reported for a positive position value. Some Synaptics firmware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * uses this value to indicate a finger near the edge of the touchpad
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * whose precise position cannot be determined.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * At least one touchpad is known to report positions in excess of this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * value which are actually negative values truncated to the 13-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * reporting range. These values have never been observed to be lower
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * than 8184 (i.e. -8), so we treat all values greater than 8176 as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * negative and any other value as positive.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define X_MAX_POSITIVE 8176
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define Y_MAX_POSITIVE 8176
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) /* maximum ABS_MT_POSITION displacement (in mm) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define DMAX 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) /*****************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * Stuff we need even when we do not want native Synaptics support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) ****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * Set the synaptics touchpad mode byte by special commands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) static int synaptics_mode_cmd(struct psmouse *psmouse, u8 mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) u8 param[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) error = ps2_sliced_command(&psmouse->ps2dev, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) param[0] = SYN_PS_SET_MODE2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) error = ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_SETRATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) int synaptics_detect(struct psmouse *psmouse, bool set_properties)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) struct ps2dev *ps2dev = &psmouse->ps2dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) u8 param[4] = { 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) if (param[1] != 0x47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) if (set_properties) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) psmouse->vendor = "Synaptics";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) psmouse->name = "TouchPad";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) void synaptics_reset(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /* reset touchpad back to relative mode, gestures enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) synaptics_mode_cmd(psmouse, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #if defined(CONFIG_MOUSE_PS2_SYNAPTICS) || \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) defined(CONFIG_MOUSE_PS2_SYNAPTICS_SMBUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) /* This list has been kindly provided by Synaptics. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static const char * const topbuttonpad_pnp_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) "LEN0017",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) "LEN0018",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) "LEN0019",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) "LEN0023",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) "LEN002A",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) "LEN002B",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) "LEN002C",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) "LEN002D",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) "LEN002E",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) "LEN0033", /* Helix */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) "LEN0034", /* T431s, L440, L540, T540, W540, X1 Carbon 2nd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) "LEN0035", /* X240 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) "LEN0036", /* T440 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) "LEN0037", /* X1 Carbon 2nd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) "LEN0038",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) "LEN0039", /* T440s */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) "LEN0041",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) "LEN0042", /* Yoga */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) "LEN0045",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) "LEN0047",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) "LEN2000", /* S540 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) "LEN2001", /* Edge E431 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) "LEN2002", /* Edge E531 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) "LEN2003",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) "LEN2004", /* L440 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) "LEN2005",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) "LEN2006", /* Edge E440/E540 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) "LEN2007",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) "LEN2008",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) "LEN2009",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) "LEN200A",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) "LEN200B",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) static const char * const smbus_pnp_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) /* all of the topbuttonpad_pnp_ids are valid, we just add some extras */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) "LEN0048", /* X1 Carbon 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) "LEN0046", /* X250 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) "LEN0049", /* Yoga 11e */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) "LEN004a", /* W541 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) "LEN005b", /* P50 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) "LEN005e", /* T560 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) "LEN006c", /* T470s */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) "LEN007a", /* T470s */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) "LEN0071", /* T480 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) "LEN0072", /* X1 Carbon Gen 5 (2017) - Elan/ALPS trackpoint */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) "LEN0073", /* X1 Carbon G5 (Elantech) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) "LEN0091", /* X1 Carbon 6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) "LEN0092", /* X1 Carbon 6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) "LEN0093", /* T480 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) "LEN0096", /* X280 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) "LEN0097", /* X280 -> ALPS trackpoint */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) "LEN0099", /* X1 Extreme Gen 1 / P1 Gen 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) "LEN009b", /* T580 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) "LEN0402", /* X1 Extreme Gen 2 / P1 Gen 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) "LEN200f", /* T450s */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) "LEN2044", /* L470 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) "LEN2054", /* E480 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) "LEN2055", /* E580 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) "LEN2068", /* T14 Gen 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) "SYN3052", /* HP EliteBook 840 G4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) "SYN3221", /* HP 15-ay000 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) "SYN323d", /* HP Spectre X360 13-w013dx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) "SYN3257", /* HP Envy 13-ad105ng */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) static const char * const forcepad_pnp_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) "SYN300D",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) "SYN3014",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * Send a command to the synaptics touchpad by special commands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) static int synaptics_send_cmd(struct psmouse *psmouse, u8 cmd, u8 *param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) error = ps2_sliced_command(&psmouse->ps2dev, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) error = ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_GETINFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) static int synaptics_query_int(struct psmouse *psmouse, u8 query_cmd, u32 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) __be32 be_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) char buf[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) } resp = { 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) error = synaptics_send_cmd(psmouse, query_cmd, resp.buf + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) *val = be32_to_cpu(resp.be_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * Identify Touchpad
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * See also the SYN_ID_* macros
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) static int synaptics_identify(struct psmouse *psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) struct synaptics_device_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) error = synaptics_query_int(psmouse, SYN_QUE_IDENTIFY, &info->identity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) return SYN_ID_IS_SYNAPTICS(info->identity) ? 0 : -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) * Read the model-id bytes from the touchpad
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * see also SYN_MODEL_* macros
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) static int synaptics_model_id(struct psmouse *psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) struct synaptics_device_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) return synaptics_query_int(psmouse, SYN_QUE_MODEL, &info->model_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) * Read the firmware id from the touchpad
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) static int synaptics_firmware_id(struct psmouse *psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) struct synaptics_device_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) return synaptics_query_int(psmouse, SYN_QUE_FIRMWARE_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) &info->firmware_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) * Read the board id and the "More Extended Queries" from the touchpad
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) * The board id is encoded in the "QUERY MODES" response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) static int synaptics_query_modes(struct psmouse *psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) struct synaptics_device_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) u8 bid[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) /* firmwares prior 7.5 have no board_id encoded */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) if (SYN_ID_FULL(info->identity) < 0x705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) error = synaptics_send_cmd(psmouse, SYN_QUE_MODES, bid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) info->board_id = ((bid[0] & 0xfc) << 6) | bid[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) if (SYN_MEXT_CAP_BIT(bid[0]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) return synaptics_query_int(psmouse, SYN_QUE_MEXT_CAPAB_10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) &info->ext_cap_10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) * Read the capability-bits from the touchpad
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) * see also the SYN_CAP_* macros
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) static int synaptics_capability(struct psmouse *psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) struct synaptics_device_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) error = synaptics_query_int(psmouse, SYN_QUE_CAPABILITIES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) &info->capabilities);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) info->ext_cap = info->ext_cap_0c = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) * Older firmwares had submodel ID fixed to 0x47
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) if (SYN_ID_FULL(info->identity) < 0x705 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) SYN_CAP_SUBMODEL_ID(info->capabilities) != 0x47) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) * Unless capExtended is set the rest of the flags should be ignored
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (!SYN_CAP_EXTENDED(info->capabilities))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) info->capabilities = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) if (SYN_EXT_CAP_REQUESTS(info->capabilities) >= 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) error = synaptics_query_int(psmouse, SYN_QUE_EXT_CAPAB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) &info->ext_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) psmouse_warn(psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) "device claims to have extended capabilities, but I'm not able to read them.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) * if nExtBtn is greater than 8 it should be considered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) * invalid and treated as 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (SYN_CAP_MULTI_BUTTON_NO(info->ext_cap) > 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) info->ext_cap &= ~SYN_CAP_MB_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) if (SYN_EXT_CAP_REQUESTS(info->capabilities) >= 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) error = synaptics_query_int(psmouse, SYN_QUE_EXT_CAPAB_0C,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) &info->ext_cap_0c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) psmouse_warn(psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) "device claims to have extended capability 0x0c, but I'm not able to read it.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) * Read touchpad resolution and maximum reported coordinates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) * Resolution is left zero if touchpad does not support the query
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) static int synaptics_resolution(struct psmouse *psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) struct synaptics_device_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) u8 resp[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) if (SYN_ID_MAJOR(info->identity) < 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) error = synaptics_send_cmd(psmouse, SYN_QUE_RESOLUTION, resp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (!error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if (resp[0] != 0 && (resp[1] & 0x80) && resp[2] != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) info->x_res = resp[0]; /* x resolution in units/mm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) info->y_res = resp[2]; /* y resolution in units/mm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) if (SYN_EXT_CAP_REQUESTS(info->capabilities) >= 5 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) SYN_CAP_MAX_DIMENSIONS(info->ext_cap_0c)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) error = synaptics_send_cmd(psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) SYN_QUE_EXT_MAX_COORDS, resp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) psmouse_warn(psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) "device claims to have max coordinates query, but I'm not able to read it.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) info->x_max = (resp[0] << 5) | ((resp[1] & 0x0f) << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) info->y_max = (resp[2] << 5) | ((resp[1] & 0xf0) >> 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) psmouse_info(psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) "queried max coordinates: x [..%d], y [..%d]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) info->x_max, info->y_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) if (SYN_CAP_MIN_DIMENSIONS(info->ext_cap_0c) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) (SYN_EXT_CAP_REQUESTS(info->capabilities) >= 7 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) * Firmware v8.1 does not report proper number of extended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) * capabilities, but has been proven to report correct min
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) * coordinates.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) SYN_ID_FULL(info->identity) == 0x801)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) error = synaptics_send_cmd(psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) SYN_QUE_EXT_MIN_COORDS, resp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) psmouse_warn(psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) "device claims to have min coordinates query, but I'm not able to read it.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) info->x_min = (resp[0] << 5) | ((resp[1] & 0x0f) << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) info->y_min = (resp[2] << 5) | ((resp[1] & 0xf0) >> 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) psmouse_info(psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) "queried min coordinates: x [%d..], y [%d..]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) info->x_min, info->y_min);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) static int synaptics_query_hardware(struct psmouse *psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) struct synaptics_device_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) memset(info, 0, sizeof(*info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) error = synaptics_identify(psmouse, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) error = synaptics_model_id(psmouse, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) error = synaptics_firmware_id(psmouse, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) error = synaptics_query_modes(psmouse, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) error = synaptics_capability(psmouse, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) error = synaptics_resolution(psmouse, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) #endif /* CONFIG_MOUSE_PS2_SYNAPTICS || CONFIG_MOUSE_PS2_SYNAPTICS_SMBUS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) #ifdef CONFIG_MOUSE_PS2_SYNAPTICS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) static bool cr48_profile_sensor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) #define ANY_BOARD_ID 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) struct min_max_quirk {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) const char * const *pnp_ids;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) u32 min, max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) } board_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) u32 x_min, x_max, y_min, y_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) static const struct min_max_quirk min_max_pnpid_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) (const char * const []){"LEN0033", NULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) {ANY_BOARD_ID, ANY_BOARD_ID},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 1024, 5052, 2258, 4832
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) (const char * const []){"LEN0042", NULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) {ANY_BOARD_ID, ANY_BOARD_ID},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 1232, 5710, 1156, 4696
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) (const char * const []){"LEN0034", "LEN0036", "LEN0037",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) "LEN0039", "LEN2002", "LEN2004",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) NULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) {ANY_BOARD_ID, 2961},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 1024, 5112, 2024, 4832
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) (const char * const []){"LEN2000", NULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) {ANY_BOARD_ID, ANY_BOARD_ID},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 1024, 5113, 2021, 4832
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) (const char * const []){"LEN2001", NULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) {ANY_BOARD_ID, ANY_BOARD_ID},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 1024, 5022, 2508, 4832
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) (const char * const []){"LEN2006", NULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) {2691, 2691},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 1024, 5045, 2457, 4832
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) (const char * const []){"LEN2006", NULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) {ANY_BOARD_ID, ANY_BOARD_ID},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 1264, 5675, 1171, 4688
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) /*****************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) * Synaptics communications functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) ****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) * Synaptics touchpads report the y coordinate from bottom to top, which is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) * opposite from what userspace expects.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) * This function is used to invert y before reporting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) static int synaptics_invert_y(int y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) return YMAX_NOMINAL + YMIN_NOMINAL - y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) * Apply quirk(s) if the hardware matches
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) static void synaptics_apply_quirks(struct psmouse *psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) struct synaptics_device_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) for (i = 0; min_max_pnpid_table[i].pnp_ids; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) if (!psmouse_matches_pnp_id(psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) min_max_pnpid_table[i].pnp_ids))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) if (min_max_pnpid_table[i].board_id.min != ANY_BOARD_ID &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) info->board_id < min_max_pnpid_table[i].board_id.min)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) if (min_max_pnpid_table[i].board_id.max != ANY_BOARD_ID &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) info->board_id > min_max_pnpid_table[i].board_id.max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) info->x_min = min_max_pnpid_table[i].x_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) info->x_max = min_max_pnpid_table[i].x_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) info->y_min = min_max_pnpid_table[i].y_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) info->y_max = min_max_pnpid_table[i].y_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) psmouse_info(psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) "quirked min/max coordinates: x [%d..%d], y [%d..%d]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) info->x_min, info->x_max,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) info->y_min, info->y_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) static bool synaptics_has_agm(struct synaptics_data *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) return (SYN_CAP_ADV_GESTURE(priv->info.ext_cap_0c) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) SYN_CAP_IMAGE_SENSOR(priv->info.ext_cap_0c));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) static int synaptics_set_advanced_gesture_mode(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) static u8 param = 0xc8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) error = ps2_sliced_command(&psmouse->ps2dev, SYN_QUE_MODEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) error = ps2_command(&psmouse->ps2dev, ¶m, PSMOUSE_CMD_SETRATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) static int synaptics_set_mode(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) struct synaptics_data *priv = psmouse->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) priv->mode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) if (priv->absolute_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) priv->mode |= SYN_BIT_ABSOLUTE_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (priv->disable_gesture)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) priv->mode |= SYN_BIT_DISABLE_GESTURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) if (psmouse->rate >= 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) priv->mode |= SYN_BIT_HIGH_RATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) if (SYN_CAP_EXTENDED(priv->info.capabilities))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) priv->mode |= SYN_BIT_W_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) error = synaptics_mode_cmd(psmouse, priv->mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) if (priv->absolute_mode && synaptics_has_agm(priv)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) error = synaptics_set_advanced_gesture_mode(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) psmouse_err(psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) "Advanced gesture mode init failed: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) static void synaptics_set_rate(struct psmouse *psmouse, unsigned int rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) struct synaptics_data *priv = psmouse->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) if (rate >= 80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) priv->mode |= SYN_BIT_HIGH_RATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) psmouse->rate = 80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) priv->mode &= ~SYN_BIT_HIGH_RATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) psmouse->rate = 40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) synaptics_mode_cmd(psmouse, priv->mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) /*****************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) * Synaptics pass-through PS/2 port support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) ****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) static int synaptics_pt_write(struct serio *serio, u8 c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) struct psmouse *parent = serio_get_drvdata(serio->parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) u8 rate_param = SYN_PS_CLIENT_CMD; /* indicates that we want pass-through port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) error = ps2_sliced_command(&parent->ps2dev, c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) error = ps2_command(&parent->ps2dev, &rate_param, PSMOUSE_CMD_SETRATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) static int synaptics_pt_start(struct serio *serio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) struct psmouse *parent = serio_get_drvdata(serio->parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) struct synaptics_data *priv = parent->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) serio_pause_rx(parent->ps2dev.serio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) priv->pt_port = serio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) serio_continue_rx(parent->ps2dev.serio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) static void synaptics_pt_stop(struct serio *serio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) struct psmouse *parent = serio_get_drvdata(serio->parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) struct synaptics_data *priv = parent->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) serio_pause_rx(parent->ps2dev.serio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) priv->pt_port = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) serio_continue_rx(parent->ps2dev.serio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) static int synaptics_is_pt_packet(u8 *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) return (buf[0] & 0xFC) == 0x84 && (buf[3] & 0xCC) == 0xC4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) static void synaptics_pass_pt_packet(struct serio *ptport, u8 *packet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) struct psmouse *child = serio_get_drvdata(ptport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) if (child && child->state == PSMOUSE_ACTIVATED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) serio_interrupt(ptport, packet[1], 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) serio_interrupt(ptport, packet[4], 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) serio_interrupt(ptport, packet[5], 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) if (child->pktsize == 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) serio_interrupt(ptport, packet[2], 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) serio_interrupt(ptport, packet[1], 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) static void synaptics_pt_activate(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) struct synaptics_data *priv = psmouse->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) struct psmouse *child = serio_get_drvdata(priv->pt_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) /* adjust the touchpad to child's choice of protocol */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) if (child) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) if (child->pktsize == 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) priv->mode |= SYN_BIT_FOUR_BYTE_CLIENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) priv->mode &= ~SYN_BIT_FOUR_BYTE_CLIENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) if (synaptics_mode_cmd(psmouse, priv->mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) psmouse_warn(psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) "failed to switch guest protocol\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) static void synaptics_pt_create(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) struct serio *serio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) if (!serio) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) psmouse_err(psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) "not enough memory for pass-through port\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) serio->id.type = SERIO_PS_PSTHRU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) strlcpy(serio->name, "Synaptics pass-through", sizeof(serio->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) strlcpy(serio->phys, "synaptics-pt/serio0", sizeof(serio->phys));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) serio->write = synaptics_pt_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) serio->start = synaptics_pt_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) serio->stop = synaptics_pt_stop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) serio->parent = psmouse->ps2dev.serio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) psmouse->pt_activate = synaptics_pt_activate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) psmouse_info(psmouse, "serio: %s port at %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) serio->name, psmouse->phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) serio_register_port(serio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) /*****************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) * Functions to interpret the absolute mode packets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) ****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) static void synaptics_parse_agm(const u8 buf[],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) struct synaptics_data *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) struct synaptics_hw_state *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) struct synaptics_hw_state *agm = &priv->agm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) int agm_packet_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) agm_packet_type = (buf[5] & 0x30) >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) switch (agm_packet_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) /* Gesture packet: (x, y, z) half resolution */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) agm->w = hw->w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) agm->x = (((buf[4] & 0x0f) << 8) | buf[1]) << 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) agm->y = (((buf[4] & 0xf0) << 4) | buf[2]) << 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) agm->z = ((buf[3] & 0x30) | (buf[5] & 0x0f)) << 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) /* AGM-CONTACT packet: we are only interested in the count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) priv->agm_count = buf[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) static void synaptics_parse_ext_buttons(const u8 buf[],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) struct synaptics_data *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) struct synaptics_hw_state *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) unsigned int ext_bits =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) (SYN_CAP_MULTI_BUTTON_NO(priv->info.ext_cap) + 1) >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) unsigned int ext_mask = GENMASK(ext_bits - 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) hw->ext_buttons = buf[4] & ext_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) hw->ext_buttons |= (buf[5] & ext_mask) << ext_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) static int synaptics_parse_hw_state(const u8 buf[],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) struct synaptics_data *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) struct synaptics_hw_state *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) memset(hw, 0, sizeof(struct synaptics_hw_state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) if (SYN_MODEL_NEWABS(priv->info.model_id)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) hw->w = (((buf[0] & 0x30) >> 2) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) ((buf[0] & 0x04) >> 1) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) ((buf[3] & 0x04) >> 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) if (synaptics_has_agm(priv) && hw->w == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) synaptics_parse_agm(buf, priv, hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) hw->x = (((buf[3] & 0x10) << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) ((buf[1] & 0x0f) << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) buf[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) hw->y = (((buf[3] & 0x20) << 7) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) ((buf[1] & 0xf0) << 4) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) buf[5]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) hw->z = buf[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) hw->left = (buf[0] & 0x01) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) hw->right = (buf[0] & 0x02) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) if (priv->is_forcepad) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) * ForcePads, like Clickpads, use middle button
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) * bits to report primary button clicks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) * Unfortunately they report primary button not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) * only when user presses on the pad above certain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) * threshold, but also when there are more than one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) * finger on the touchpad, which interferes with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) * out multi-finger gestures.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) if (hw->z == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) /* No contacts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) priv->press = priv->report_press = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) } else if (hw->w >= 4 && ((buf[0] ^ buf[3]) & 0x01)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) * Single-finger touch with pressure above
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) * the threshold. If pressure stays long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) * enough, we'll start reporting primary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) * button. We rely on the device continuing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) * sending data even if finger does not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) * move.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) if (!priv->press) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) priv->press_start = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) priv->press = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) } else if (time_after(jiffies,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) priv->press_start +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) msecs_to_jiffies(50))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) priv->report_press = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) priv->press = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) hw->left = priv->report_press;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) } else if (SYN_CAP_CLICKPAD(priv->info.ext_cap_0c)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) * Clickpad's button is transmitted as middle button,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) * however, since it is primary button, we will report
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) * it as BTN_LEFT.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) hw->left = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) } else if (SYN_CAP_MIDDLE_BUTTON(priv->info.capabilities)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) hw->middle = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) if (hw->w == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) hw->scroll = (s8)buf[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) if (SYN_CAP_FOUR_BUTTON(priv->info.capabilities)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) hw->up = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) hw->down = ((buf[0] ^ buf[3]) & 0x02) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) if (SYN_CAP_MULTI_BUTTON_NO(priv->info.ext_cap) > 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) ((buf[0] ^ buf[3]) & 0x02)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) synaptics_parse_ext_buttons(buf, priv, hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) hw->x = (((buf[1] & 0x1f) << 8) | buf[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) hw->y = (((buf[4] & 0x1f) << 8) | buf[5]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) hw->z = (((buf[0] & 0x30) << 2) | (buf[3] & 0x3F));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) hw->w = (((buf[1] & 0x80) >> 4) | ((buf[0] & 0x04) >> 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) hw->left = (buf[0] & 0x01) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) hw->right = (buf[0] & 0x02) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) * Convert wrap-around values to negative. (X|Y)_MAX_POSITIVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) * is used by some firmware to indicate a finger at the edge of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) * the touchpad whose precise position cannot be determined, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) * convert these values to the maximum axis value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) if (hw->x > X_MAX_POSITIVE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) hw->x -= 1 << ABS_POS_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) else if (hw->x == X_MAX_POSITIVE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) hw->x = XMAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) if (hw->y > Y_MAX_POSITIVE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) hw->y -= 1 << ABS_POS_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) else if (hw->y == Y_MAX_POSITIVE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) hw->y = YMAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) static void synaptics_report_semi_mt_slot(struct input_dev *dev, int slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) bool active, int x, int y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) input_mt_slot(dev, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) input_mt_report_slot_state(dev, MT_TOOL_FINGER, active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) if (active) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) input_report_abs(dev, ABS_MT_POSITION_X, x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) input_report_abs(dev, ABS_MT_POSITION_Y, synaptics_invert_y(y));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) static void synaptics_report_semi_mt_data(struct input_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) const struct synaptics_hw_state *a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) const struct synaptics_hw_state *b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) int num_fingers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) if (num_fingers >= 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) synaptics_report_semi_mt_slot(dev, 0, true, min(a->x, b->x),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) min(a->y, b->y));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) synaptics_report_semi_mt_slot(dev, 1, true, max(a->x, b->x),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) max(a->y, b->y));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) } else if (num_fingers == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) synaptics_report_semi_mt_slot(dev, 0, true, a->x, a->y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) synaptics_report_semi_mt_slot(dev, 1, false, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) synaptics_report_semi_mt_slot(dev, 0, false, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) synaptics_report_semi_mt_slot(dev, 1, false, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) static void synaptics_report_ext_buttons(struct psmouse *psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) const struct synaptics_hw_state *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) struct input_dev *dev = psmouse->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) struct synaptics_data *priv = psmouse->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) int ext_bits = (SYN_CAP_MULTI_BUTTON_NO(priv->info.ext_cap) + 1) >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) if (!SYN_CAP_MULTI_BUTTON_NO(priv->info.ext_cap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) /* Bug in FW 8.1 & 8.2, buttons are reported only when ExtBit is 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) if ((SYN_ID_FULL(priv->info.identity) == 0x801 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) SYN_ID_FULL(priv->info.identity) == 0x802) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) !((psmouse->packet[0] ^ psmouse->packet[3]) & 0x02))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) if (!SYN_CAP_EXT_BUTTONS_STICK(priv->info.ext_cap_10)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) for (i = 0; i < ext_bits; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) input_report_key(dev, BTN_0 + 2 * i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) hw->ext_buttons & BIT(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) input_report_key(dev, BTN_1 + 2 * i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) hw->ext_buttons & BIT(i + ext_bits));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) * This generation of touchpads has the trackstick buttons
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) * physically wired to the touchpad. Re-route them through
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) * the pass-through interface.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) if (priv->pt_port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) u8 pt_buttons;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) /* The trackstick expects at most 3 buttons */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) pt_buttons = SYN_EXT_BUTTON_STICK_L(hw->ext_buttons) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) SYN_EXT_BUTTON_STICK_R(hw->ext_buttons) << 1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) SYN_EXT_BUTTON_STICK_M(hw->ext_buttons) << 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) serio_interrupt(priv->pt_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) PSMOUSE_OOB_EXTRA_BTNS, SERIO_OOB_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) serio_interrupt(priv->pt_port, pt_buttons, SERIO_OOB_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) static void synaptics_report_buttons(struct psmouse *psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) const struct synaptics_hw_state *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) struct input_dev *dev = psmouse->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) struct synaptics_data *priv = psmouse->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) input_report_key(dev, BTN_LEFT, hw->left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) input_report_key(dev, BTN_RIGHT, hw->right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) if (SYN_CAP_MIDDLE_BUTTON(priv->info.capabilities))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) input_report_key(dev, BTN_MIDDLE, hw->middle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) if (SYN_CAP_FOUR_BUTTON(priv->info.capabilities)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) input_report_key(dev, BTN_FORWARD, hw->up);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) input_report_key(dev, BTN_BACK, hw->down);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) synaptics_report_ext_buttons(psmouse, hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) static void synaptics_report_mt_data(struct psmouse *psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) const struct synaptics_hw_state *sgm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) int num_fingers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) struct input_dev *dev = psmouse->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) struct synaptics_data *priv = psmouse->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) const struct synaptics_hw_state *hw[2] = { sgm, &priv->agm };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) struct input_mt_pos pos[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) int slot[2], nsemi, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) nsemi = clamp_val(num_fingers, 0, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) for (i = 0; i < nsemi; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) pos[i].x = hw[i]->x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) pos[i].y = synaptics_invert_y(hw[i]->y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) input_mt_assign_slots(dev, slot, pos, nsemi, DMAX * priv->info.x_res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) for (i = 0; i < nsemi; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) input_mt_slot(dev, slot[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) input_mt_report_slot_state(dev, MT_TOOL_FINGER, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) input_report_abs(dev, ABS_MT_POSITION_X, pos[i].x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) input_report_abs(dev, ABS_MT_POSITION_Y, pos[i].y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) input_report_abs(dev, ABS_MT_PRESSURE, hw[i]->z);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) input_mt_drop_unused(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) /* Don't use active slot count to generate BTN_TOOL events. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) input_mt_report_pointer_emulation(dev, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) /* Send the number of fingers reported by touchpad itself. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) input_mt_report_finger_count(dev, num_fingers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) synaptics_report_buttons(psmouse, sgm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) input_sync(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) static void synaptics_image_sensor_process(struct psmouse *psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) struct synaptics_hw_state *sgm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) struct synaptics_data *priv = psmouse->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) int num_fingers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) * Update mt_state using the new finger count and current mt_state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) if (sgm->z == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) num_fingers = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) else if (sgm->w >= 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) num_fingers = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) else if (sgm->w == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) num_fingers = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) else if (sgm->w == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) num_fingers = priv->agm_count ? priv->agm_count : 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) num_fingers = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) /* Send resulting input events to user space */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) synaptics_report_mt_data(psmouse, sgm, num_fingers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) static bool synaptics_has_multifinger(struct synaptics_data *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) if (SYN_CAP_MULTIFINGER(priv->info.capabilities))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) /* Advanced gesture mode also sends multi finger data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) return synaptics_has_agm(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) * called for each full received packet from the touchpad
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) static void synaptics_process_packet(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) struct input_dev *dev = psmouse->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) struct synaptics_data *priv = psmouse->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) struct synaptics_device_info *info = &priv->info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) struct synaptics_hw_state hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) int num_fingers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) int finger_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) if (synaptics_parse_hw_state(psmouse->packet, priv, &hw))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) if (SYN_CAP_IMAGE_SENSOR(info->ext_cap_0c)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) synaptics_image_sensor_process(psmouse, &hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) if (hw.scroll) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) priv->scroll += hw.scroll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) while (priv->scroll >= 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) input_report_key(dev, BTN_BACK, !hw.down);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) input_sync(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) input_report_key(dev, BTN_BACK, hw.down);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) input_sync(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) priv->scroll -= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) while (priv->scroll <= -4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) input_report_key(dev, BTN_FORWARD, !hw.up);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) input_sync(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) input_report_key(dev, BTN_FORWARD, hw.up);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) input_sync(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) priv->scroll += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) if (hw.z > 0 && hw.x > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) num_fingers = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) finger_width = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) if (SYN_CAP_EXTENDED(info->capabilities)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) switch (hw.w) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) case 0 ... 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) if (synaptics_has_multifinger(priv))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) num_fingers = hw.w + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) if (SYN_MODEL_PEN(info->model_id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) ; /* Nothing, treat a pen as a single finger */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) case 4 ... 15:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) if (SYN_CAP_PALMDETECT(info->capabilities))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) finger_width = hw.w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) num_fingers = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) finger_width = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) if (cr48_profile_sensor) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) synaptics_report_mt_data(psmouse, &hw, num_fingers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) if (SYN_CAP_ADV_GESTURE(info->ext_cap_0c))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) synaptics_report_semi_mt_data(dev, &hw, &priv->agm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) num_fingers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) /* Post events
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) * BTN_TOUCH has to be first as mousedev relies on it when doing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) * absolute -> relative conversion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) if (hw.z > 30) input_report_key(dev, BTN_TOUCH, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) if (hw.z < 25) input_report_key(dev, BTN_TOUCH, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) if (num_fingers > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) input_report_abs(dev, ABS_X, hw.x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) input_report_abs(dev, ABS_Y, synaptics_invert_y(hw.y));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) input_report_abs(dev, ABS_PRESSURE, hw.z);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) if (SYN_CAP_PALMDETECT(info->capabilities))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) input_report_abs(dev, ABS_TOOL_WIDTH, finger_width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) input_report_key(dev, BTN_TOOL_FINGER, num_fingers == 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) if (synaptics_has_multifinger(priv)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) input_report_key(dev, BTN_TOOL_DOUBLETAP, num_fingers == 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) input_report_key(dev, BTN_TOOL_TRIPLETAP, num_fingers == 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) synaptics_report_buttons(psmouse, &hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) input_sync(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) static bool synaptics_validate_byte(struct psmouse *psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) int idx, enum synaptics_pkt_type pkt_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) static const u8 newabs_mask[] = { 0xC8, 0x00, 0x00, 0xC8, 0x00 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) static const u8 newabs_rel_mask[] = { 0xC0, 0x00, 0x00, 0xC0, 0x00 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) static const u8 newabs_rslt[] = { 0x80, 0x00, 0x00, 0xC0, 0x00 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) static const u8 oldabs_mask[] = { 0xC0, 0x60, 0x00, 0xC0, 0x60 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) static const u8 oldabs_rslt[] = { 0xC0, 0x00, 0x00, 0x80, 0x00 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) const u8 *packet = psmouse->packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) if (idx < 0 || idx > 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) switch (pkt_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) case SYN_NEWABS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) case SYN_NEWABS_RELAXED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) return (packet[idx] & newabs_rel_mask[idx]) == newabs_rslt[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) case SYN_NEWABS_STRICT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) return (packet[idx] & newabs_mask[idx]) == newabs_rslt[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) case SYN_OLDABS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) return (packet[idx] & oldabs_mask[idx]) == oldabs_rslt[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) psmouse_err(psmouse, "unknown packet type %d\n", pkt_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) static enum synaptics_pkt_type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) synaptics_detect_pkt_type(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) for (i = 0; i < 5; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) if (!synaptics_validate_byte(psmouse, i, SYN_NEWABS_STRICT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) psmouse_info(psmouse, "using relaxed packet validation\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) return SYN_NEWABS_RELAXED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) return SYN_NEWABS_STRICT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) static psmouse_ret_t synaptics_process_byte(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) struct synaptics_data *priv = psmouse->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) if (psmouse->pktcnt >= 6) { /* Full packet received */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) if (unlikely(priv->pkt_type == SYN_NEWABS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) priv->pkt_type = synaptics_detect_pkt_type(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) if (SYN_CAP_PASS_THROUGH(priv->info.capabilities) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) synaptics_is_pt_packet(psmouse->packet)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) if (priv->pt_port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) synaptics_pass_pt_packet(priv->pt_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) psmouse->packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) synaptics_process_packet(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) return PSMOUSE_FULL_PACKET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) return synaptics_validate_byte(psmouse, psmouse->pktcnt - 1, priv->pkt_type) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) PSMOUSE_GOOD_DATA : PSMOUSE_BAD_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) /*****************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) * Driver initialization/cleanup functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) ****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) static void set_abs_position_params(struct input_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) struct synaptics_device_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) int x_code, int y_code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) int x_min = info->x_min ?: XMIN_NOMINAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) int x_max = info->x_max ?: XMAX_NOMINAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) int y_min = info->y_min ?: YMIN_NOMINAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) int y_max = info->y_max ?: YMAX_NOMINAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) int fuzz = SYN_CAP_REDUCED_FILTERING(info->ext_cap_0c) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) SYN_REDUCED_FILTER_FUZZ : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) input_set_abs_params(dev, x_code, x_min, x_max, fuzz, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) input_set_abs_params(dev, y_code, y_min, y_max, fuzz, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) input_abs_set_res(dev, x_code, info->x_res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) input_abs_set_res(dev, y_code, info->y_res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) static int set_input_params(struct psmouse *psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) struct synaptics_data *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) struct input_dev *dev = psmouse->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) struct synaptics_device_info *info = &priv->info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) /* Reset default psmouse capabilities */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) __clear_bit(EV_REL, dev->evbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) bitmap_zero(dev->relbit, REL_CNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) bitmap_zero(dev->keybit, KEY_CNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) /* Things that apply to both modes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) __set_bit(INPUT_PROP_POINTER, dev->propbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) input_set_capability(dev, EV_KEY, BTN_LEFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) /* Clickpads report only left button */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) if (!SYN_CAP_CLICKPAD(info->ext_cap_0c)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) input_set_capability(dev, EV_KEY, BTN_RIGHT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) if (SYN_CAP_MIDDLE_BUTTON(info->capabilities))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) input_set_capability(dev, EV_KEY, BTN_MIDDLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) if (!priv->absolute_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) /* Relative mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) input_set_capability(dev, EV_REL, REL_X);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) input_set_capability(dev, EV_REL, REL_Y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) /* Absolute mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) set_abs_position_params(dev, &priv->info, ABS_X, ABS_Y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) if (cr48_profile_sensor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) input_set_abs_params(dev, ABS_MT_PRESSURE, 0, 255, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) if (SYN_CAP_IMAGE_SENSOR(info->ext_cap_0c)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) set_abs_position_params(dev, info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) ABS_MT_POSITION_X, ABS_MT_POSITION_Y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) /* Image sensors can report per-contact pressure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) input_set_abs_params(dev, ABS_MT_PRESSURE, 0, 255, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) error = input_mt_init_slots(dev, 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) INPUT_MT_POINTER | INPUT_MT_TRACK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) /* Image sensors can signal 4 and 5 finger clicks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) input_set_capability(dev, EV_KEY, BTN_TOOL_QUADTAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) input_set_capability(dev, EV_KEY, BTN_TOOL_QUINTTAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) } else if (SYN_CAP_ADV_GESTURE(info->ext_cap_0c)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) set_abs_position_params(dev, info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) ABS_MT_POSITION_X, ABS_MT_POSITION_Y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) * Profile sensor in CR-48 tracks contacts reasonably well,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) * other non-image sensors with AGM use semi-mt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) error = input_mt_init_slots(dev, 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) INPUT_MT_POINTER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) (cr48_profile_sensor ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) INPUT_MT_TRACK :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) INPUT_MT_SEMI_MT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) * For semi-mt devices we send ABS_X/Y ourselves instead of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) * input_mt_report_pointer_emulation. But
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) * input_mt_init_slots() resets the fuzz to 0, leading to a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) * filtered ABS_MT_POSITION_X but an unfiltered ABS_X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) * position. Let's re-initialize ABS_X/Y here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) if (!cr48_profile_sensor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) set_abs_position_params(dev, &priv->info, ABS_X, ABS_Y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) if (SYN_CAP_PALMDETECT(info->capabilities))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) input_set_abs_params(dev, ABS_TOOL_WIDTH, 0, 15, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) input_set_capability(dev, EV_KEY, BTN_TOUCH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) input_set_capability(dev, EV_KEY, BTN_TOOL_FINGER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) if (synaptics_has_multifinger(priv)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) input_set_capability(dev, EV_KEY, BTN_TOOL_DOUBLETAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) input_set_capability(dev, EV_KEY, BTN_TOOL_TRIPLETAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) if (SYN_CAP_FOUR_BUTTON(info->capabilities) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) SYN_CAP_MIDDLE_BUTTON(info->capabilities)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) input_set_capability(dev, EV_KEY, BTN_FORWARD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) input_set_capability(dev, EV_KEY, BTN_BACK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) if (!SYN_CAP_EXT_BUTTONS_STICK(info->ext_cap_10))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(info->ext_cap); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) input_set_capability(dev, EV_KEY, BTN_0 + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) if (SYN_CAP_CLICKPAD(info->ext_cap_0c)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) if (psmouse_matches_pnp_id(psmouse, topbuttonpad_pnp_ids) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) !SYN_CAP_EXT_BUTTONS_STICK(info->ext_cap_10))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) __set_bit(INPUT_PROP_TOPBUTTONPAD, dev->propbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) static ssize_t synaptics_show_disable_gesture(struct psmouse *psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) void *data, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) struct synaptics_data *priv = psmouse->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) return sprintf(buf, "%c\n", priv->disable_gesture ? '1' : '0');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) static ssize_t synaptics_set_disable_gesture(struct psmouse *psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) void *data, const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) struct synaptics_data *priv = psmouse->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) unsigned int value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) err = kstrtouint(buf, 10, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) if (value > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) if (value == priv->disable_gesture)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) priv->disable_gesture = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) if (value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) priv->mode |= SYN_BIT_DISABLE_GESTURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) priv->mode &= ~SYN_BIT_DISABLE_GESTURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) if (synaptics_mode_cmd(psmouse, priv->mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) PSMOUSE_DEFINE_ATTR(disable_gesture, S_IWUSR | S_IRUGO, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) synaptics_show_disable_gesture,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) synaptics_set_disable_gesture);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) static void synaptics_disconnect(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) struct synaptics_data *priv = psmouse->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) * We might have left a breadcrumb when trying to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) * set up SMbus companion.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) psmouse_smbus_cleanup(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) if (!priv->absolute_mode &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) SYN_ID_DISGEST_SUPPORTED(priv->info.identity))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) device_remove_file(&psmouse->ps2dev.serio->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) &psmouse_attr_disable_gesture.dattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) synaptics_reset(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) kfree(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) psmouse->private = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) static int synaptics_reconnect(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) struct synaptics_data *priv = psmouse->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) struct synaptics_device_info info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) u8 param[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) int retry = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) psmouse_reset(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) if (retry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) * On some boxes, right after resuming, the touchpad
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) * needs some time to finish initializing (I assume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) * it needs time to calibrate) and start responding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) * to Synaptics-specific queries, so let's wait a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) * bit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) ssleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_GETID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) error = synaptics_detect(psmouse, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) } while (error && ++retry < 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) if (retry > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) psmouse_dbg(psmouse, "reconnected after %d tries\n", retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) error = synaptics_query_hardware(psmouse, &info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) psmouse_err(psmouse, "Unable to query device.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) error = synaptics_set_mode(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) psmouse_err(psmouse, "Unable to initialize device.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) if (info.identity != priv->info.identity ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) info.model_id != priv->info.model_id ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) info.capabilities != priv->info.capabilities ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) info.ext_cap != priv->info.ext_cap) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) psmouse_err(psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) "hardware appears to be different: id(%u-%u), model(%u-%u), caps(%x-%x), ext(%x-%x).\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) priv->info.identity, info.identity,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) priv->info.model_id, info.model_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) priv->info.capabilities, info.capabilities,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) priv->info.ext_cap, info.ext_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) static bool impaired_toshiba_kbc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) static const struct dmi_system_id toshiba_dmi_table[] __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) #if defined(CONFIG_DMI) && defined(CONFIG_X86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) /* Toshiba Satellite */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) DMI_MATCH(DMI_PRODUCT_NAME, "Satellite"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) /* Toshiba Dynabook */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) DMI_MATCH(DMI_PRODUCT_NAME, "dynabook"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) /* Toshiba Portege M300 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) /* Toshiba Portege M300 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) DMI_MATCH(DMI_PRODUCT_NAME, "Portable PC"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) DMI_MATCH(DMI_PRODUCT_VERSION, "Version 1.0"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) static bool broken_olpc_ec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) static const struct dmi_system_id olpc_dmi_table[] __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) #if defined(CONFIG_DMI) && defined(CONFIG_OLPC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) /* OLPC XO-1 or XO-1.5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) DMI_MATCH(DMI_SYS_VENDOR, "OLPC"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) DMI_MATCH(DMI_PRODUCT_NAME, "XO"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) static const struct dmi_system_id __initconst cr48_dmi_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) #if defined(CONFIG_DMI) && defined(CONFIG_X86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) /* Cr-48 Chromebook (Codename Mario) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) DMI_MATCH(DMI_SYS_VENDOR, "IEC"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) DMI_MATCH(DMI_PRODUCT_NAME, "Mario"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) void __init synaptics_module_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) impaired_toshiba_kbc = dmi_check_system(toshiba_dmi_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) broken_olpc_ec = dmi_check_system(olpc_dmi_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) cr48_profile_sensor = dmi_check_system(cr48_dmi_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) static int synaptics_init_ps2(struct psmouse *psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) struct synaptics_device_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) bool absolute_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) struct synaptics_data *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) synaptics_apply_quirks(psmouse, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) psmouse->private = priv = kzalloc(sizeof(struct synaptics_data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) if (!priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) priv->info = *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) priv->absolute_mode = absolute_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) if (SYN_ID_DISGEST_SUPPORTED(info->identity))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) priv->disable_gesture = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) * Unfortunately ForcePad capability is not exported over PS/2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) * so we have to resort to checking PNP IDs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) priv->is_forcepad = psmouse_matches_pnp_id(psmouse, forcepad_pnp_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) err = synaptics_set_mode(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) psmouse_err(psmouse, "Unable to initialize device.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) goto init_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) priv->pkt_type = SYN_MODEL_NEWABS(info->model_id) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) SYN_NEWABS : SYN_OLDABS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) psmouse_info(psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) "Touchpad model: %lu, fw: %lu.%lu, id: %#x, caps: %#x/%#x/%#x/%#x, board id: %u, fw id: %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) SYN_ID_MODEL(info->identity),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) SYN_ID_MAJOR(info->identity), SYN_ID_MINOR(info->identity),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) info->model_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) info->capabilities, info->ext_cap, info->ext_cap_0c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) info->ext_cap_10, info->board_id, info->firmware_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) err = set_input_params(psmouse, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) psmouse_err(psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) "failed to set up capabilities: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) goto init_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) * Encode touchpad model so that it can be used to set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) * input device->id.version and be visible to userspace.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) * Because version is __u16 we have to drop something.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) * Hardware info bits seem to be good candidates as they
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) * are documented to be for Synaptics corp. internal use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) psmouse->model = ((info->model_id & 0x00ff0000) >> 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) (info->model_id & 0x000000ff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) if (absolute_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) psmouse->protocol_handler = synaptics_process_byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) psmouse->pktsize = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) /* Relative mode follows standard PS/2 mouse protocol */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) psmouse->protocol_handler = psmouse_process_byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) psmouse->pktsize = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) psmouse->set_rate = synaptics_set_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) psmouse->disconnect = synaptics_disconnect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) psmouse->reconnect = synaptics_reconnect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) psmouse->cleanup = synaptics_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) /* Synaptics can usually stay in sync without extra help */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) psmouse->resync_time = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) if (SYN_CAP_PASS_THROUGH(info->capabilities))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) synaptics_pt_create(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) * Toshiba's KBC seems to have trouble handling data from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) * Synaptics at full rate. Switch to a lower rate (roughly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) * the same rate as a standard PS/2 mouse).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) if (psmouse->rate >= 80 && impaired_toshiba_kbc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) psmouse_info(psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) "Toshiba %s detected, limiting rate to 40pps.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) dmi_get_system_info(DMI_PRODUCT_NAME));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) psmouse->rate = 40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) if (!priv->absolute_mode && SYN_ID_DISGEST_SUPPORTED(info->identity)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) err = device_create_file(&psmouse->ps2dev.serio->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) &psmouse_attr_disable_gesture.dattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) psmouse_err(psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) "Failed to create disable_gesture attribute (%d)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) goto init_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) init_fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) kfree(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) struct synaptics_device_info info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) psmouse_reset(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) error = synaptics_query_hardware(psmouse, &info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) psmouse_err(psmouse, "Unable to query device: %d\n", error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) return synaptics_init_ps2(psmouse, &info, absolute_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) int synaptics_init_absolute(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) return __synaptics_init(psmouse, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) int synaptics_init_relative(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) return __synaptics_init(psmouse, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) static int synaptics_setup_ps2(struct psmouse *psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) struct synaptics_device_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) bool absolute_mode = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) * The OLPC XO has issues with Synaptics' absolute mode; the constant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) * packet spew overloads the EC such that key presses on the keyboard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) * are missed. Given that, don't even attempt to use Absolute mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) * Relative mode seems to work just fine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) if (broken_olpc_ec) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) psmouse_info(psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) "OLPC XO detected, forcing relative protocol.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) absolute_mode = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) error = synaptics_init_ps2(psmouse, info, absolute_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) return absolute_mode ? PSMOUSE_SYNAPTICS : PSMOUSE_SYNAPTICS_RELATIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) #else /* CONFIG_MOUSE_PS2_SYNAPTICS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) void __init synaptics_module_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) static int __maybe_unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) synaptics_setup_ps2(struct psmouse *psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) struct synaptics_device_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) return -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) #endif /* CONFIG_MOUSE_PS2_SYNAPTICS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) #ifdef CONFIG_MOUSE_PS2_SYNAPTICS_SMBUS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) * The newest Synaptics device can use a secondary bus (called InterTouch) which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) * provides a better bandwidth and allow a better control of the touchpads.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) * This is used to decide if we need to use this bus or not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) SYNAPTICS_INTERTOUCH_NOT_SET = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) SYNAPTICS_INTERTOUCH_OFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) SYNAPTICS_INTERTOUCH_ON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) static int synaptics_intertouch = IS_ENABLED(CONFIG_RMI4_SMB) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) SYNAPTICS_INTERTOUCH_NOT_SET : SYNAPTICS_INTERTOUCH_OFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) module_param_named(synaptics_intertouch, synaptics_intertouch, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) MODULE_PARM_DESC(synaptics_intertouch, "Use a secondary bus for the Synaptics device.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) static int synaptics_create_intertouch(struct psmouse *psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) struct synaptics_device_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) bool leave_breadcrumbs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) bool topbuttonpad =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) psmouse_matches_pnp_id(psmouse, topbuttonpad_pnp_ids) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) !SYN_CAP_EXT_BUTTONS_STICK(info->ext_cap_10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) const struct rmi_device_platform_data pdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) .sensor_pdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) .sensor_type = rmi_sensor_touchpad,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) .axis_align.flip_y = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) .kernel_tracking = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) .topbuttonpad = topbuttonpad,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) .gpio_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) .buttonpad = SYN_CAP_CLICKPAD(info->ext_cap_0c),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) .trackstick_buttons =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) !!SYN_CAP_EXT_BUTTONS_STICK(info->ext_cap_10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) const struct i2c_board_info intertouch_board = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) I2C_BOARD_INFO("rmi4_smbus", 0x2c),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) .flags = I2C_CLIENT_HOST_NOTIFY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) return psmouse_smbus_init(psmouse, &intertouch_board,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) &pdata, sizeof(pdata), true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) leave_breadcrumbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) * synaptics_setup_intertouch - called once the PS/2 devices are enumerated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) * and decides to instantiate a SMBus InterTouch device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) static int synaptics_setup_intertouch(struct psmouse *psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) struct synaptics_device_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) bool leave_breadcrumbs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) if (synaptics_intertouch == SYNAPTICS_INTERTOUCH_OFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) if (synaptics_intertouch == SYNAPTICS_INTERTOUCH_NOT_SET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) if (!psmouse_matches_pnp_id(psmouse, topbuttonpad_pnp_ids) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) !psmouse_matches_pnp_id(psmouse, smbus_pnp_ids)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) if (!psmouse_matches_pnp_id(psmouse, forcepad_pnp_ids))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) psmouse_info(psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) "Your touchpad (%s) says it can support a different bus. "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) "If i2c-hid and hid-rmi are not used, you might want to try setting psmouse.synaptics_intertouch to 1 and report this to linux-input@vger.kernel.org.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) psmouse->ps2dev.serio->firmware_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) psmouse_info(psmouse, "Trying to set up SMBus access\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) error = synaptics_create_intertouch(psmouse, info, leave_breadcrumbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) if (error == -EAGAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) psmouse_info(psmouse, "SMbus companion is not ready yet\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) psmouse_err(psmouse, "unable to create intertouch device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) int synaptics_init_smbus(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) struct synaptics_device_info info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) psmouse_reset(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) error = synaptics_query_hardware(psmouse, &info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) psmouse_err(psmouse, "Unable to query device: %d\n", error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) if (!SYN_CAP_INTERTOUCH(info.ext_cap_0c))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) return synaptics_create_intertouch(psmouse, &info, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) #else /* CONFIG_MOUSE_PS2_SYNAPTICS_SMBUS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) static int __maybe_unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) synaptics_setup_intertouch(struct psmouse *psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) struct synaptics_device_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) bool leave_breadcrumbs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) return -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) int synaptics_init_smbus(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) return -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) #endif /* CONFIG_MOUSE_PS2_SYNAPTICS_SMBUS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) #if defined(CONFIG_MOUSE_PS2_SYNAPTICS) || \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) defined(CONFIG_MOUSE_PS2_SYNAPTICS_SMBUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) int synaptics_init(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) struct synaptics_device_info info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) psmouse_reset(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) error = synaptics_query_hardware(psmouse, &info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) psmouse_err(psmouse, "Unable to query device: %d\n", error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) if (SYN_CAP_INTERTOUCH(info.ext_cap_0c)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) if ((!IS_ENABLED(CONFIG_RMI4_SMB) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) !IS_ENABLED(CONFIG_MOUSE_PS2_SYNAPTICS_SMBUS)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) /* Forcepads need F21, which is not ready */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) !psmouse_matches_pnp_id(psmouse, forcepad_pnp_ids)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) psmouse_warn(psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) "The touchpad can support a better bus than the too old PS/2 protocol. "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) "Make sure MOUSE_PS2_SYNAPTICS_SMBUS and RMI4_SMB are enabled to get a better touchpad experience.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) error = synaptics_setup_intertouch(psmouse, &info, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) if (!error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) return PSMOUSE_SYNAPTICS_SMBUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) retval = synaptics_setup_ps2(psmouse, &info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) if (retval < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) * Not using any flavor of Synaptics support, so clean up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) * SMbus breadcrumbs, if any.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) psmouse_smbus_cleanup(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) #else /* CONFIG_MOUSE_PS2_SYNAPTICS || CONFIG_MOUSE_PS2_SYNAPTICS_SMBUS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) int synaptics_init(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) return -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) #endif /* CONFIG_MOUSE_PS2_SYNAPTICS || CONFIG_MOUSE_PS2_SYNAPTICS_SMBUS */