LCOV - code coverage report
Current view: top level - drivers/input/mouse - synaptics.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 5 670 0.7 %
Date: 2023-08-24 13:40:31 Functions: 1 47 2.1 %

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

Generated by: LCOV version 1.14