LCOV - code coverage report
Current view: top level - drivers/input/mouse - alps.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 790 0.0 %
Date: 2014-02-18 Functions: 0 54 0.0 %
Branches: 0 574 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * ALPS touchpad PS/2 mouse driver
       3                 :            :  *
       4                 :            :  * Copyright (c) 2003 Neil Brown <neilb@cse.unsw.edu.au>
       5                 :            :  * Copyright (c) 2003-2005 Peter Osterlund <petero2@telia.com>
       6                 :            :  * Copyright (c) 2004 Dmitry Torokhov <dtor@mail.ru>
       7                 :            :  * Copyright (c) 2005 Vojtech Pavlik <vojtech@suse.cz>
       8                 :            :  * Copyright (c) 2009 Sebastian Kapfer <sebastian_kapfer@gmx.net>
       9                 :            :  *
      10                 :            :  * ALPS detection, tap switching and status querying info is taken from
      11                 :            :  * tpconfig utility (by C. Scott Ananian and Bruce Kall).
      12                 :            :  *
      13                 :            :  * This program is free software; you can redistribute it and/or modify it
      14                 :            :  * under the terms of the GNU General Public License version 2 as published by
      15                 :            :  * the Free Software Foundation.
      16                 :            :  */
      17                 :            : 
      18                 :            : #include <linux/slab.h>
      19                 :            : #include <linux/input.h>
      20                 :            : #include <linux/input/mt.h>
      21                 :            : #include <linux/serio.h>
      22                 :            : #include <linux/libps2.h>
      23                 :            : 
      24                 :            : #include "psmouse.h"
      25                 :            : #include "alps.h"
      26                 :            : 
      27                 :            : /*
      28                 :            :  * Definitions for ALPS version 3 and 4 command mode protocol
      29                 :            :  */
      30                 :            : #define ALPS_CMD_NIBBLE_10      0x01f2
      31                 :            : 
      32                 :            : #define ALPS_REG_BASE_RUSHMORE  0xc2c0
      33                 :            : #define ALPS_REG_BASE_PINNACLE  0x0000
      34                 :            : 
      35                 :            : static const struct alps_nibble_commands alps_v3_nibble_commands[] = {
      36                 :            :         { PSMOUSE_CMD_SETPOLL,          0x00 }, /* 0 */
      37                 :            :         { PSMOUSE_CMD_RESET_DIS,        0x00 }, /* 1 */
      38                 :            :         { PSMOUSE_CMD_SETSCALE21,       0x00 }, /* 2 */
      39                 :            :         { PSMOUSE_CMD_SETRATE,          0x0a }, /* 3 */
      40                 :            :         { PSMOUSE_CMD_SETRATE,          0x14 }, /* 4 */
      41                 :            :         { PSMOUSE_CMD_SETRATE,          0x28 }, /* 5 */
      42                 :            :         { PSMOUSE_CMD_SETRATE,          0x3c }, /* 6 */
      43                 :            :         { PSMOUSE_CMD_SETRATE,          0x50 }, /* 7 */
      44                 :            :         { PSMOUSE_CMD_SETRATE,          0x64 }, /* 8 */
      45                 :            :         { PSMOUSE_CMD_SETRATE,          0xc8 }, /* 9 */
      46                 :            :         { ALPS_CMD_NIBBLE_10,           0x00 }, /* a */
      47                 :            :         { PSMOUSE_CMD_SETRES,           0x00 }, /* b */
      48                 :            :         { PSMOUSE_CMD_SETRES,           0x01 }, /* c */
      49                 :            :         { PSMOUSE_CMD_SETRES,           0x02 }, /* d */
      50                 :            :         { PSMOUSE_CMD_SETRES,           0x03 }, /* e */
      51                 :            :         { PSMOUSE_CMD_SETSCALE11,       0x00 }, /* f */
      52                 :            : };
      53                 :            : 
      54                 :            : static const struct alps_nibble_commands alps_v4_nibble_commands[] = {
      55                 :            :         { PSMOUSE_CMD_ENABLE,           0x00 }, /* 0 */
      56                 :            :         { PSMOUSE_CMD_RESET_DIS,        0x00 }, /* 1 */
      57                 :            :         { PSMOUSE_CMD_SETSCALE21,       0x00 }, /* 2 */
      58                 :            :         { PSMOUSE_CMD_SETRATE,          0x0a }, /* 3 */
      59                 :            :         { PSMOUSE_CMD_SETRATE,          0x14 }, /* 4 */
      60                 :            :         { PSMOUSE_CMD_SETRATE,          0x28 }, /* 5 */
      61                 :            :         { PSMOUSE_CMD_SETRATE,          0x3c }, /* 6 */
      62                 :            :         { PSMOUSE_CMD_SETRATE,          0x50 }, /* 7 */
      63                 :            :         { PSMOUSE_CMD_SETRATE,          0x64 }, /* 8 */
      64                 :            :         { PSMOUSE_CMD_SETRATE,          0xc8 }, /* 9 */
      65                 :            :         { ALPS_CMD_NIBBLE_10,           0x00 }, /* a */
      66                 :            :         { PSMOUSE_CMD_SETRES,           0x00 }, /* b */
      67                 :            :         { PSMOUSE_CMD_SETRES,           0x01 }, /* c */
      68                 :            :         { PSMOUSE_CMD_SETRES,           0x02 }, /* d */
      69                 :            :         { PSMOUSE_CMD_SETRES,           0x03 }, /* e */
      70                 :            :         { PSMOUSE_CMD_SETSCALE11,       0x00 }, /* f */
      71                 :            : };
      72                 :            : 
      73                 :            : static const struct alps_nibble_commands alps_v6_nibble_commands[] = {
      74                 :            :         { PSMOUSE_CMD_ENABLE,           0x00 }, /* 0 */
      75                 :            :         { PSMOUSE_CMD_SETRATE,          0x0a }, /* 1 */
      76                 :            :         { PSMOUSE_CMD_SETRATE,          0x14 }, /* 2 */
      77                 :            :         { PSMOUSE_CMD_SETRATE,          0x28 }, /* 3 */
      78                 :            :         { PSMOUSE_CMD_SETRATE,          0x3c }, /* 4 */
      79                 :            :         { PSMOUSE_CMD_SETRATE,          0x50 }, /* 5 */
      80                 :            :         { PSMOUSE_CMD_SETRATE,          0x64 }, /* 6 */
      81                 :            :         { PSMOUSE_CMD_SETRATE,          0xc8 }, /* 7 */
      82                 :            :         { PSMOUSE_CMD_GETID,            0x00 }, /* 8 */
      83                 :            :         { PSMOUSE_CMD_GETINFO,          0x00 }, /* 9 */
      84                 :            :         { PSMOUSE_CMD_SETRES,           0x00 }, /* a */
      85                 :            :         { PSMOUSE_CMD_SETRES,           0x01 }, /* b */
      86                 :            :         { PSMOUSE_CMD_SETRES,           0x02 }, /* c */
      87                 :            :         { PSMOUSE_CMD_SETRES,           0x03 }, /* d */
      88                 :            :         { PSMOUSE_CMD_SETSCALE21,       0x00 }, /* e */
      89                 :            :         { PSMOUSE_CMD_SETSCALE11,       0x00 }, /* f */
      90                 :            : };
      91                 :            : 
      92                 :            : 
      93                 :            : #define ALPS_DUALPOINT          0x02    /* touchpad has trackstick */
      94                 :            : #define ALPS_PASS               0x04    /* device has a pass-through port */
      95                 :            : 
      96                 :            : #define ALPS_WHEEL              0x08    /* hardware wheel present */
      97                 :            : #define ALPS_FW_BK_1            0x10    /* front & back buttons present */
      98                 :            : #define ALPS_FW_BK_2            0x20    /* front & back buttons present */
      99                 :            : #define ALPS_FOUR_BUTTONS       0x40    /* 4 direction button present */
     100                 :            : #define ALPS_PS2_INTERLEAVED    0x80    /* 3-byte PS/2 packet interleaved with
     101                 :            :                                            6-byte ALPS packet */
     102                 :            : 
     103                 :            : static const struct alps_model_info alps_model_data[] = {
     104                 :            :         { { 0x32, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT },  /* Toshiba Salellite Pro M10 */
     105                 :            :         { { 0x33, 0x02, 0x0a }, 0x00, ALPS_PROTO_V1, 0x88, 0xf8, 0 },                           /* UMAX-530T */
     106                 :            :         { { 0x53, 0x02, 0x0a }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
     107                 :            :         { { 0x53, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
     108                 :            :         { { 0x60, 0x03, 0xc8 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },                           /* HP ze1115 */
     109                 :            :         { { 0x63, 0x02, 0x0a }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
     110                 :            :         { { 0x63, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
     111                 :            :         { { 0x63, 0x02, 0x28 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_FW_BK_2 },                /* Fujitsu Siemens S6010 */
     112                 :            :         { { 0x63, 0x02, 0x3c }, 0x00, ALPS_PROTO_V2, 0x8f, 0x8f, ALPS_WHEEL },                  /* Toshiba Satellite S2400-103 */
     113                 :            :         { { 0x63, 0x02, 0x50 }, 0x00, ALPS_PROTO_V2, 0xef, 0xef, ALPS_FW_BK_1 },                /* NEC Versa L320 */
     114                 :            :         { { 0x63, 0x02, 0x64 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
     115                 :            :         { { 0x63, 0x03, 0xc8 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT },  /* Dell Latitude D800 */
     116                 :            :         { { 0x73, 0x00, 0x0a }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_DUALPOINT },              /* ThinkPad R61 8918-5QG */
     117                 :            :         { { 0x73, 0x02, 0x0a }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
     118                 :            :         { { 0x73, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_FW_BK_2 },                /* Ahtec Laptop */
     119                 :            :         { { 0x20, 0x02, 0x0e }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT },  /* XXX */
     120                 :            :         { { 0x22, 0x02, 0x0a }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT },
     121                 :            :         { { 0x22, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT },  /* Dell Latitude D600 */
     122                 :            :         /* Dell Latitude E5500, E6400, E6500, Precision M4400 */
     123                 :            :         { { 0x62, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xcf, 0xcf,
     124                 :            :                 ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED },
     125                 :            :         { { 0x73, 0x00, 0x14 }, 0x00, ALPS_PROTO_V6, 0xff, 0xff, ALPS_DUALPOINT },              /* Dell XT2 */
     126                 :            :         { { 0x73, 0x02, 0x50 }, 0x00, ALPS_PROTO_V2, 0xcf, 0xcf, ALPS_FOUR_BUTTONS },           /* Dell Vostro 1400 */
     127                 :            :         { { 0x52, 0x01, 0x14 }, 0x00, ALPS_PROTO_V2, 0xff, 0xff,
     128                 :            :                 ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED },                            /* Toshiba Tecra A11-11L */
     129                 :            :         { { 0x73, 0x02, 0x64 }, 0x8a, ALPS_PROTO_V4, 0x8f, 0x8f, 0 },
     130                 :            : };
     131                 :            : 
     132                 :            : static void alps_set_abs_params_st(struct alps_data *priv,
     133                 :            :                                    struct input_dev *dev1);
     134                 :            : static void alps_set_abs_params_mt(struct alps_data *priv,
     135                 :            :                                    struct input_dev *dev1);
     136                 :            : 
     137                 :            : /*
     138                 :            :  * XXX - this entry is suspicious. First byte has zero lower nibble,
     139                 :            :  * which is what a normal mouse would report. Also, the value 0x0e
     140                 :            :  * isn't valid per PS/2 spec.
     141                 :            :  */
     142                 :            : 
     143                 :            : /* Packet formats are described in Documentation/input/alps.txt */
     144                 :            : 
     145                 :            : static bool alps_is_valid_first_byte(struct alps_data *priv,
     146                 :            :                                      unsigned char data)
     147                 :            : {
     148                 :          0 :         return (data & priv->mask0) == priv->byte0;
     149                 :            : }
     150                 :            : 
     151                 :          0 : static void alps_report_buttons(struct psmouse *psmouse,
     152                 :            :                                 struct input_dev *dev1, struct input_dev *dev2,
     153                 :            :                                 int left, int right, int middle)
     154                 :            : {
     155                 :            :         struct input_dev *dev;
     156                 :            : 
     157                 :            :         /*
     158                 :            :          * If shared button has already been reported on the
     159                 :            :          * other device (dev2) then this event should be also
     160                 :            :          * sent through that device.
     161                 :            :          */
     162         [ #  # ]:          0 :         dev = test_bit(BTN_LEFT, dev2->key) ? dev2 : dev1;
     163                 :            :         input_report_key(dev, BTN_LEFT, left);
     164                 :            : 
     165         [ #  # ]:          0 :         dev = test_bit(BTN_RIGHT, dev2->key) ? dev2 : dev1;
     166                 :            :         input_report_key(dev, BTN_RIGHT, right);
     167                 :            : 
     168         [ #  # ]:          0 :         dev = test_bit(BTN_MIDDLE, dev2->key) ? dev2 : dev1;
     169                 :            :         input_report_key(dev, BTN_MIDDLE, middle);
     170                 :            : 
     171                 :            :         /*
     172                 :            :          * Sync the _other_ device now, we'll do the first
     173                 :            :          * device later once we report the rest of the events.
     174                 :            :          */
     175                 :            :         input_sync(dev2);
     176                 :          0 : }
     177                 :            : 
     178                 :          0 : static void alps_process_packet_v1_v2(struct psmouse *psmouse)
     179                 :            : {
     180                 :          0 :         struct alps_data *priv = psmouse->private;
     181                 :            :         unsigned char *packet = psmouse->packet;
     182                 :          0 :         struct input_dev *dev = psmouse->dev;
     183                 :          0 :         struct input_dev *dev2 = priv->dev2;
     184                 :            :         int x, y, z, ges, fin, left, right, middle;
     185                 :            :         int back = 0, forward = 0;
     186                 :            : 
     187         [ #  # ]:          0 :         if (priv->proto_version == ALPS_PROTO_V1) {
     188                 :          0 :                 left = packet[2] & 0x10;
     189                 :          0 :                 right = packet[2] & 0x08;
     190                 :            :                 middle = 0;
     191                 :          0 :                 x = packet[1] | ((packet[0] & 0x07) << 7);
     192                 :          0 :                 y = packet[4] | ((packet[3] & 0x07) << 7);
     193                 :          0 :                 z = packet[5];
     194                 :            :         } else {
     195                 :          0 :                 left = packet[3] & 1;
     196                 :          0 :                 right = packet[3] & 2;
     197                 :          0 :                 middle = packet[3] & 4;
     198                 :          0 :                 x = packet[1] | ((packet[2] & 0x78) << (7 - 3));
     199                 :          0 :                 y = packet[4] | ((packet[3] & 0x70) << (7 - 4));
     200                 :          0 :                 z = packet[5];
     201                 :            :         }
     202                 :            : 
     203         [ #  # ]:          0 :         if (priv->flags & ALPS_FW_BK_1) {
     204                 :          0 :                 back = packet[0] & 0x10;
     205                 :          0 :                 forward = packet[2] & 4;
     206                 :            :         }
     207                 :            : 
     208         [ #  # ]:          0 :         if (priv->flags & ALPS_FW_BK_2) {
     209                 :          0 :                 back = packet[3] & 4;
     210                 :          0 :                 forward = packet[2] & 4;
     211         [ #  # ]:          0 :                 if ((middle = forward && back))
     212                 :            :                         forward = back = 0;
     213                 :            :         }
     214                 :            : 
     215                 :          0 :         ges = packet[2] & 1;
     216                 :          0 :         fin = packet[2] & 2;
     217                 :            : 
     218 [ #  # ][ #  # ]:          0 :         if ((priv->flags & ALPS_DUALPOINT) && z == 127) {
     219         [ #  # ]:          0 :                 input_report_rel(dev2, REL_X,  (x > 383 ? (x - 768) : x));
     220         [ #  # ]:          0 :                 input_report_rel(dev2, REL_Y, -(y > 255 ? (y - 512) : y));
     221                 :            : 
     222                 :          0 :                 alps_report_buttons(psmouse, dev2, dev, left, right, middle);
     223                 :            : 
     224                 :            :                 input_sync(dev2);
     225                 :          0 :                 return;
     226                 :            :         }
     227                 :            : 
     228                 :          0 :         alps_report_buttons(psmouse, dev, dev2, left, right, middle);
     229                 :            : 
     230                 :            :         /* Convert hardware tap to a reasonable Z value */
     231         [ #  # ]:          0 :         if (ges && !fin)
     232                 :            :                 z = 40;
     233                 :            : 
     234                 :            :         /*
     235                 :            :          * A "tap and drag" operation is reported by the hardware as a transition
     236                 :            :          * from (!fin && ges) to (fin && ges). This should be translated to the
     237                 :            :          * sequence Z>0, Z==0, Z>0, so the Z==0 event has to be generated manually.
     238                 :            :          */
     239 [ #  # ][ #  # ]:          0 :         if (ges && fin && !priv->prev_fin) {
     240                 :            :                 input_report_abs(dev, ABS_X, x);
     241                 :            :                 input_report_abs(dev, ABS_Y, y);
     242                 :            :                 input_report_abs(dev, ABS_PRESSURE, 0);
     243                 :            :                 input_report_key(dev, BTN_TOOL_FINGER, 0);
     244                 :            :                 input_sync(dev);
     245                 :            :         }
     246                 :          0 :         priv->prev_fin = fin;
     247                 :            : 
     248         [ #  # ]:          0 :         if (z > 30)
     249                 :            :                 input_report_key(dev, BTN_TOUCH, 1);
     250         [ #  # ]:          0 :         if (z < 25)
     251                 :            :                 input_report_key(dev, BTN_TOUCH, 0);
     252                 :            : 
     253         [ #  # ]:          0 :         if (z > 0) {
     254                 :            :                 input_report_abs(dev, ABS_X, x);
     255                 :            :                 input_report_abs(dev, ABS_Y, y);
     256                 :            :         }
     257                 :            : 
     258                 :            :         input_report_abs(dev, ABS_PRESSURE, z);
     259                 :          0 :         input_report_key(dev, BTN_TOOL_FINGER, z > 0);
     260                 :            : 
     261         [ #  # ]:          0 :         if (priv->flags & ALPS_WHEEL)
     262                 :          0 :                 input_report_rel(dev, REL_WHEEL, ((packet[2] << 1) & 0x08) - ((packet[0] >> 4) & 0x07));
     263                 :            : 
     264         [ #  # ]:          0 :         if (priv->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) {
     265                 :            :                 input_report_key(dev, BTN_FORWARD, forward);
     266                 :            :                 input_report_key(dev, BTN_BACK, back);
     267                 :            :         }
     268                 :            : 
     269         [ #  # ]:          0 :         if (priv->flags & ALPS_FOUR_BUTTONS) {
     270                 :          0 :                 input_report_key(dev, BTN_0, packet[2] & 4);
     271                 :          0 :                 input_report_key(dev, BTN_1, packet[0] & 0x10);
     272                 :          0 :                 input_report_key(dev, BTN_2, packet[3] & 4);
     273                 :          0 :                 input_report_key(dev, BTN_3, packet[0] & 0x20);
     274                 :            :         }
     275                 :            : 
     276                 :            :         input_sync(dev);
     277                 :            : }
     278                 :            : 
     279                 :            : /*
     280                 :            :  * Process bitmap data from v3 and v4 protocols. Returns the number of
     281                 :            :  * fingers detected. A return value of 0 means at least one of the
     282                 :            :  * bitmaps was empty.
     283                 :            :  *
     284                 :            :  * The bitmaps don't have enough data to track fingers, so this function
     285                 :            :  * only generates points representing a bounding box of all contacts.
     286                 :            :  * These points are returned in x1, y1, x2, and y2 when the return value
     287                 :            :  * is greater than 0.
     288                 :            :  */
     289                 :          0 : static int alps_process_bitmap(struct alps_data *priv,
     290                 :            :                                unsigned int x_map, unsigned int y_map,
     291                 :            :                                int *x1, int *y1, int *x2, int *y2)
     292                 :            : {
     293                 :            :         struct alps_bitmap_point {
     294                 :            :                 int start_bit;
     295                 :            :                 int num_bits;
     296                 :            :         };
     297                 :            : 
     298                 :            :         int fingers_x = 0, fingers_y = 0, fingers;
     299                 :            :         int i, bit, prev_bit;
     300                 :          0 :         struct alps_bitmap_point x_low = {0,}, x_high = {0,};
     301                 :          0 :         struct alps_bitmap_point y_low = {0,}, y_high = {0,};
     302                 :            :         struct alps_bitmap_point *point;
     303                 :            : 
     304         [ #  # ]:          0 :         if (!x_map || !y_map)
     305                 :            :                 return 0;
     306                 :            : 
     307                 :          0 :         *x1 = *y1 = *x2 = *y2 = 0;
     308                 :            : 
     309                 :            :         prev_bit = 0;
     310                 :            :         point = &x_low;
     311         [ #  # ]:          0 :         for (i = 0; x_map != 0; i++, x_map >>= 1) {
     312                 :          0 :                 bit = x_map & 1;
     313         [ #  # ]:          0 :                 if (bit) {
     314         [ #  # ]:          0 :                         if (!prev_bit) {
     315                 :          0 :                                 point->start_bit = i;
     316                 :          0 :                                 fingers_x++;
     317                 :            :                         }
     318                 :          0 :                         point->num_bits++;
     319                 :            :                 } else {
     320         [ #  # ]:          0 :                         if (prev_bit)
     321                 :            :                                 point = &x_high;
     322                 :            :                         else
     323                 :          0 :                                 point->num_bits = 0;
     324                 :            :                 }
     325                 :            :                 prev_bit = bit;
     326                 :            :         }
     327                 :            : 
     328                 :            :         /*
     329                 :            :          * y bitmap is reversed for what we need (lower positions are in
     330                 :            :          * higher bits), so we process from the top end.
     331                 :            :          */
     332                 :          0 :         y_map = y_map << (sizeof(y_map) * BITS_PER_BYTE - priv->y_bits);
     333                 :            :         prev_bit = 0;
     334                 :            :         point = &y_low;
     335         [ #  # ]:          0 :         for (i = 0; y_map != 0; i++, y_map <<= 1) {
     336                 :          0 :                 bit = y_map & (1 << (sizeof(y_map) * BITS_PER_BYTE - 1));
     337         [ #  # ]:          0 :                 if (bit) {
     338         [ #  # ]:          0 :                         if (!prev_bit) {
     339                 :          0 :                                 point->start_bit = i;
     340                 :          0 :                                 fingers_y++;
     341                 :            :                         }
     342                 :          0 :                         point->num_bits++;
     343                 :            :                 } else {
     344         [ #  # ]:          0 :                         if (prev_bit)
     345                 :            :                                 point = &y_high;
     346                 :            :                         else
     347                 :          0 :                                 point->num_bits = 0;
     348                 :            :                 }
     349                 :            :                 prev_bit = bit;
     350                 :            :         }
     351                 :            : 
     352                 :            :         /*
     353                 :            :          * Fingers can overlap, so we use the maximum count of fingers
     354                 :            :          * on either axis as the finger count.
     355                 :            :          */
     356                 :          0 :         fingers = max(fingers_x, fingers_y);
     357                 :            : 
     358                 :            :         /*
     359                 :            :          * If total fingers is > 1 but either axis reports only a single
     360                 :            :          * contact, we have overlapping or adjacent fingers. For the
     361                 :            :          * purposes of creating a bounding box, divide the single contact
     362                 :            :          * (roughly) equally between the two points.
     363                 :            :          */
     364         [ #  # ]:          0 :         if (fingers > 1) {
     365         [ #  # ]:          0 :                 if (fingers_x == 1) {
     366                 :          0 :                         i = x_low.num_bits / 2;
     367                 :          0 :                         x_low.num_bits = x_low.num_bits - i;
     368                 :          0 :                         x_high.start_bit = x_low.start_bit + i;
     369                 :          0 :                         x_high.num_bits = max(i, 1);
     370         [ #  # ]:          0 :                 } else if (fingers_y == 1) {
     371                 :          0 :                         i = y_low.num_bits / 2;
     372                 :          0 :                         y_low.num_bits = y_low.num_bits - i;
     373                 :          0 :                         y_high.start_bit = y_low.start_bit + i;
     374                 :          0 :                         y_high.num_bits = max(i, 1);
     375                 :            :                 }
     376                 :            :         }
     377                 :            : 
     378                 :          0 :         *x1 = (priv->x_max * (2 * x_low.start_bit + x_low.num_bits - 1)) /
     379                 :          0 :               (2 * (priv->x_bits - 1));
     380                 :          0 :         *y1 = (priv->y_max * (2 * y_low.start_bit + y_low.num_bits - 1)) /
     381                 :          0 :               (2 * (priv->y_bits - 1));
     382                 :            : 
     383         [ #  # ]:          0 :         if (fingers > 1) {
     384                 :          0 :                 *x2 = (priv->x_max *
     385                 :          0 :                        (2 * x_high.start_bit + x_high.num_bits - 1)) /
     386                 :          0 :                       (2 * (priv->x_bits - 1));
     387                 :          0 :                 *y2 = (priv->y_max *
     388                 :          0 :                        (2 * y_high.start_bit + y_high.num_bits - 1)) /
     389                 :          0 :                       (2 * (priv->y_bits - 1));
     390                 :            :         }
     391                 :            : 
     392                 :          0 :         return fingers;
     393                 :            : }
     394                 :            : 
     395                 :          0 : static void alps_set_slot(struct input_dev *dev, int slot, bool active,
     396                 :            :                           int x, int y)
     397                 :            : {
     398                 :            :         input_mt_slot(dev, slot);
     399                 :          0 :         input_mt_report_slot_state(dev, MT_TOOL_FINGER, active);
     400         [ #  # ]:          0 :         if (active) {
     401                 :            :                 input_report_abs(dev, ABS_MT_POSITION_X, x);
     402                 :            :                 input_report_abs(dev, ABS_MT_POSITION_Y, y);
     403                 :            :         }
     404                 :          0 : }
     405                 :            : 
     406                 :          0 : static void alps_report_semi_mt_data(struct input_dev *dev, int num_fingers,
     407                 :            :                                      int x1, int y1, int x2, int y2)
     408                 :            : {
     409                 :          0 :         alps_set_slot(dev, 0, num_fingers != 0, x1, y1);
     410                 :          0 :         alps_set_slot(dev, 1, num_fingers == 2, x2, y2);
     411                 :          0 : }
     412                 :            : 
     413                 :          0 : static void alps_process_trackstick_packet_v3(struct psmouse *psmouse)
     414                 :            : {
     415                 :          0 :         struct alps_data *priv = psmouse->private;
     416                 :            :         unsigned char *packet = psmouse->packet;
     417                 :          0 :         struct input_dev *dev = priv->dev2;
     418                 :            :         int x, y, z, left, right, middle;
     419                 :            : 
     420                 :            :         /* Sanity check packet */
     421         [ #  # ]:          0 :         if (!(packet[0] & 0x40)) {
     422                 :            :                 psmouse_dbg(psmouse, "Bad trackstick packet, discarding\n");
     423                 :            :                 return;
     424                 :            :         }
     425                 :            : 
     426                 :            :         /*
     427                 :            :          * There's a special packet that seems to indicate the end
     428                 :            :          * of a stream of trackstick data. Filter these out.
     429                 :            :          */
     430 [ #  # ][ #  # ]:          0 :         if (packet[1] == 0x7f && packet[2] == 0x7f && packet[4] == 0x7f)
                 [ #  # ]
     431                 :            :                 return;
     432                 :            : 
     433                 :          0 :         x = (s8)(((packet[0] & 0x20) << 2) | (packet[1] & 0x7f));
     434                 :          0 :         y = (s8)(((packet[0] & 0x10) << 3) | (packet[2] & 0x7f));
     435                 :            :         z = (packet[4] & 0x7c) >> 2;
     436                 :            : 
     437                 :            :         /*
     438                 :            :          * The x and y values tend to be quite large, and when used
     439                 :            :          * alone the trackstick is difficult to use. Scale them down
     440                 :            :          * to compensate.
     441                 :            :          */
     442                 :          0 :         x /= 8;
     443                 :          0 :         y /= 8;
     444                 :            : 
     445                 :            :         input_report_rel(dev, REL_X, x);
     446                 :          0 :         input_report_rel(dev, REL_Y, -y);
     447                 :            : 
     448                 :            :         /*
     449                 :            :          * Most ALPS models report the trackstick buttons in the touchpad
     450                 :            :          * packets, but a few report them here. No reliable way has been
     451                 :            :          * found to differentiate between the models upfront, so we enable
     452                 :            :          * the quirk in response to seeing a button press in the trackstick
     453                 :            :          * packet.
     454                 :            :          */
     455                 :          0 :         left = packet[3] & 0x01;
     456                 :          0 :         right = packet[3] & 0x02;
     457                 :          0 :         middle = packet[3] & 0x04;
     458                 :            : 
     459 [ #  # ][ #  # ]:          0 :         if (!(priv->quirks & ALPS_QUIRK_TRACKSTICK_BUTTONS) &&
     460                 :          0 :             (left || right || middle))
     461                 :          0 :                 priv->quirks |= ALPS_QUIRK_TRACKSTICK_BUTTONS;
     462                 :            : 
     463         [ #  # ]:          0 :         if (priv->quirks & ALPS_QUIRK_TRACKSTICK_BUTTONS) {
     464                 :            :                 input_report_key(dev, BTN_LEFT, left);
     465                 :            :                 input_report_key(dev, BTN_RIGHT, right);
     466                 :            :                 input_report_key(dev, BTN_MIDDLE, middle);
     467                 :            :         }
     468                 :            : 
     469                 :            :         input_sync(dev);
     470                 :            :         return;
     471                 :            : }
     472                 :            : 
     473                 :          0 : static void alps_decode_buttons_v3(struct alps_fields *f, unsigned char *p)
     474                 :            : {
     475                 :          0 :         f->left = !!(p[3] & 0x01);
     476                 :          0 :         f->right = !!(p[3] & 0x02);
     477                 :          0 :         f->middle = !!(p[3] & 0x04);
     478                 :            : 
     479                 :          0 :         f->ts_left = !!(p[3] & 0x10);
     480                 :          0 :         f->ts_right = !!(p[3] & 0x20);
     481                 :          0 :         f->ts_middle = !!(p[3] & 0x40);
     482                 :          0 : }
     483                 :            : 
     484                 :          0 : static void alps_decode_pinnacle(struct alps_fields *f, unsigned char *p)
     485                 :            : {
     486                 :          0 :         f->first_mp = !!(p[4] & 0x40);
     487                 :          0 :         f->is_mp = !!(p[0] & 0x40);
     488                 :            : 
     489                 :          0 :         f->fingers = (p[5] & 0x3) + 1;
     490                 :          0 :         f->x_map = ((p[4] & 0x7e) << 8) |
     491                 :          0 :                    ((p[1] & 0x7f) << 2) |
     492                 :          0 :                    ((p[0] & 0x30) >> 4);
     493                 :          0 :         f->y_map = ((p[3] & 0x70) << 4) |
     494                 :          0 :                    ((p[2] & 0x7f) << 1) |
     495                 :          0 :                    (p[4] & 0x01);
     496                 :            : 
     497                 :          0 :         f->x = ((p[1] & 0x7f) << 4) | ((p[4] & 0x30) >> 2) |
     498                 :          0 :                ((p[0] & 0x30) >> 4);
     499                 :          0 :         f->y = ((p[2] & 0x7f) << 4) | (p[4] & 0x0f);
     500                 :          0 :         f->z = p[5] & 0x7f;
     501                 :            : 
     502                 :          0 :         alps_decode_buttons_v3(f, p);
     503                 :          0 : }
     504                 :            : 
     505                 :          0 : static void alps_decode_rushmore(struct alps_fields *f, unsigned char *p)
     506                 :            : {
     507                 :          0 :         alps_decode_pinnacle(f, p);
     508                 :            : 
     509                 :          0 :         f->x_map |= (p[5] & 0x10) << 11;
     510                 :          0 :         f->y_map |= (p[5] & 0x20) << 6;
     511                 :          0 : }
     512                 :            : 
     513                 :          0 : static void alps_decode_dolphin(struct alps_fields *f, unsigned char *p)
     514                 :            : {
     515                 :          0 :         f->first_mp = !!(p[0] & 0x02);
     516                 :          0 :         f->is_mp = !!(p[0] & 0x20);
     517                 :            : 
     518                 :          0 :         f->fingers = ((p[0] & 0x6) >> 1 |
     519                 :          0 :                      (p[0] & 0x10) >> 2);
     520                 :          0 :         f->x_map = ((p[2] & 0x60) >> 5) |
     521                 :          0 :                    ((p[4] & 0x7f) << 2) |
     522                 :          0 :                    ((p[5] & 0x7f) << 9) |
     523                 :          0 :                    ((p[3] & 0x07) << 16) |
     524                 :          0 :                    ((p[3] & 0x70) << 15) |
     525                 :          0 :                    ((p[0] & 0x01) << 22);
     526                 :          0 :         f->y_map = (p[1] & 0x7f) |
     527                 :          0 :                    ((p[2] & 0x1f) << 7);
     528                 :            : 
     529                 :          0 :         f->x = ((p[1] & 0x7f) | ((p[4] & 0x0f) << 7));
     530                 :          0 :         f->y = ((p[2] & 0x7f) | ((p[4] & 0xf0) << 3));
     531         [ #  # ]:          0 :         f->z = (p[0] & 4) ? 0 : p[5] & 0x7f;
     532                 :            : 
     533                 :          0 :         alps_decode_buttons_v3(f, p);
     534                 :          0 : }
     535                 :            : 
     536                 :          0 : static void alps_process_touchpad_packet_v3(struct psmouse *psmouse)
     537                 :            : {
     538                 :          0 :         struct alps_data *priv = psmouse->private;
     539                 :          0 :         unsigned char *packet = psmouse->packet;
     540                 :          0 :         struct input_dev *dev = psmouse->dev;
     541                 :          0 :         struct input_dev *dev2 = priv->dev2;
     542                 :          0 :         int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
     543                 :            :         int fingers = 0, bmap_fingers;
     544                 :            :         struct alps_fields f;
     545                 :            : 
     546                 :          0 :         priv->decode_fields(&f, packet);
     547                 :            : 
     548                 :            :         /*
     549                 :            :          * There's no single feature of touchpad position and bitmap packets
     550                 :            :          * that can be used to distinguish between them. We rely on the fact
     551                 :            :          * that a bitmap packet should always follow a position packet with
     552                 :            :          * bit 6 of packet[4] set.
     553                 :            :          */
     554         [ #  # ]:          0 :         if (priv->multi_packet) {
     555                 :            :                 /*
     556                 :            :                  * Sometimes a position packet will indicate a multi-packet
     557                 :            :                  * sequence, but then what follows is another position
     558                 :            :                  * packet. Check for this, and when it happens process the
     559                 :            :                  * position packet as usual.
     560                 :            :                  */
     561         [ #  # ]:          0 :                 if (f.is_mp) {
     562                 :          0 :                         fingers = f.fingers;
     563                 :          0 :                         bmap_fingers = alps_process_bitmap(priv,
     564                 :            :                                                            f.x_map, f.y_map,
     565                 :            :                                                            &x1, &y1, &x2, &y2);
     566                 :            : 
     567                 :            :                         /*
     568                 :            :                          * We shouldn't report more than one finger if
     569                 :            :                          * we don't have two coordinates.
     570                 :            :                          */
     571         [ #  # ]:          0 :                         if (fingers > 1 && bmap_fingers < 2)
     572                 :            :                                 fingers = bmap_fingers;
     573                 :            : 
     574                 :            :                         /* Now process position packet */
     575                 :          0 :                         priv->decode_fields(&f, priv->multi_data);
     576                 :            :                 } else {
     577                 :          0 :                         priv->multi_packet = 0;
     578                 :            :                 }
     579                 :            :         }
     580                 :            : 
     581                 :            :         /*
     582                 :            :          * Bit 6 of byte 0 is not usually set in position packets. The only
     583                 :            :          * times it seems to be set is in situations where the data is
     584                 :            :          * suspect anyway, e.g. a palm resting flat on the touchpad. Given
     585                 :            :          * this combined with the fact that this bit is useful for filtering
     586                 :            :          * out misidentified bitmap packets, we reject anything with this
     587                 :            :          * bit set.
     588                 :            :          */
     589         [ #  # ]:          0 :         if (f.is_mp)
     590                 :          0 :                 return;
     591                 :            : 
     592 [ #  # ][ #  # ]:          0 :         if (!priv->multi_packet && f.first_mp) {
     593                 :          0 :                 priv->multi_packet = 1;
     594                 :          0 :                 memcpy(priv->multi_data, packet, sizeof(priv->multi_data));
     595                 :          0 :                 return;
     596                 :            :         }
     597                 :            : 
     598                 :          0 :         priv->multi_packet = 0;
     599                 :            : 
     600                 :            :         /*
     601                 :            :          * Sometimes the hardware sends a single packet with z = 0
     602                 :            :          * in the middle of a stream. Real releases generate packets
     603                 :            :          * with x, y, and z all zero, so these seem to be flukes.
     604                 :            :          * Ignore them.
     605                 :            :          */
     606 [ #  # ][ #  # ]:          0 :         if (f.x && f.y && !f.z)
                 [ #  # ]
     607                 :            :                 return;
     608                 :            : 
     609                 :            :         /*
     610                 :            :          * If we don't have MT data or the bitmaps were empty, we have
     611                 :            :          * to rely on ST data.
     612                 :            :          */
     613         [ #  # ]:          0 :         if (!fingers) {
     614                 :          0 :                 x1 = f.x;
     615                 :          0 :                 y1 = f.y;
     616                 :          0 :                 fingers = f.z > 0 ? 1 : 0;
     617                 :            :         }
     618                 :            : 
     619         [ #  # ]:          0 :         if (f.z >= 64)
     620                 :            :                 input_report_key(dev, BTN_TOUCH, 1);
     621                 :            :         else
     622                 :            :                 input_report_key(dev, BTN_TOUCH, 0);
     623                 :            : 
     624                 :          0 :         alps_report_semi_mt_data(dev, fingers, x1, y1, x2, y2);
     625                 :            : 
     626                 :          0 :         input_mt_report_finger_count(dev, fingers);
     627                 :            : 
     628                 :          0 :         input_report_key(dev, BTN_LEFT, f.left);
     629                 :          0 :         input_report_key(dev, BTN_RIGHT, f.right);
     630                 :          0 :         input_report_key(dev, BTN_MIDDLE, f.middle);
     631                 :            : 
     632         [ #  # ]:          0 :         if (f.z > 0) {
     633                 :          0 :                 input_report_abs(dev, ABS_X, f.x);
     634                 :          0 :                 input_report_abs(dev, ABS_Y, f.y);
     635                 :            :         }
     636                 :          0 :         input_report_abs(dev, ABS_PRESSURE, f.z);
     637                 :            : 
     638                 :            :         input_sync(dev);
     639                 :            : 
     640         [ #  # ]:          0 :         if (!(priv->quirks & ALPS_QUIRK_TRACKSTICK_BUTTONS)) {
     641                 :          0 :                 input_report_key(dev2, BTN_LEFT, f.ts_left);
     642                 :          0 :                 input_report_key(dev2, BTN_RIGHT, f.ts_right);
     643                 :          0 :                 input_report_key(dev2, BTN_MIDDLE, f.ts_middle);
     644                 :            :                 input_sync(dev2);
     645                 :            :         }
     646                 :            : }
     647                 :            : 
     648                 :          0 : static void alps_process_packet_v3(struct psmouse *psmouse)
     649                 :            : {
     650                 :            :         unsigned char *packet = psmouse->packet;
     651                 :            : 
     652                 :            :         /*
     653                 :            :          * v3 protocol packets come in three types, two representing
     654                 :            :          * touchpad data and one representing trackstick data.
     655                 :            :          * Trackstick packets seem to be distinguished by always
     656                 :            :          * having 0x3f in the last byte. This value has never been
     657                 :            :          * observed in the last byte of either of the other types
     658                 :            :          * of packets.
     659                 :            :          */
     660         [ #  # ]:          0 :         if (packet[5] == 0x3f) {
     661                 :          0 :                 alps_process_trackstick_packet_v3(psmouse);
     662                 :          0 :                 return;
     663                 :            :         }
     664                 :            : 
     665                 :          0 :         alps_process_touchpad_packet_v3(psmouse);
     666                 :            : }
     667                 :            : 
     668                 :          0 : static void alps_process_packet_v6(struct psmouse *psmouse)
     669                 :            : {
     670                 :          0 :         struct alps_data *priv = psmouse->private;
     671                 :            :         unsigned char *packet = psmouse->packet;
     672                 :          0 :         struct input_dev *dev = psmouse->dev;
     673                 :          0 :         struct input_dev *dev2 = priv->dev2;
     674                 :            :         int x, y, z, left, right, middle;
     675                 :            : 
     676                 :            :         /*
     677                 :            :          * We can use Byte5 to distinguish if the packet is from Touchpad
     678                 :            :          * or Trackpoint.
     679                 :            :          * Touchpad:    0 - 0x7E
     680                 :            :          * Trackpoint:  0x7F
     681                 :            :          */
     682         [ #  # ]:          0 :         if (packet[5] == 0x7F) {
     683                 :            :                 /* It should be a DualPoint when received Trackpoint packet */
     684         [ #  # ]:          0 :                 if (!(priv->flags & ALPS_DUALPOINT))
     685                 :            :                         return;
     686                 :            : 
     687                 :            :                 /* Trackpoint packet */
     688                 :          0 :                 x = packet[1] | ((packet[3] & 0x20) << 2);
     689                 :          0 :                 y = packet[2] | ((packet[3] & 0x40) << 1);
     690                 :          0 :                 z = packet[4];
     691                 :          0 :                 left = packet[3] & 0x01;
     692                 :          0 :                 right = packet[3] & 0x02;
     693                 :          0 :                 middle = packet[3] & 0x04;
     694                 :            : 
     695                 :            :                 /* To prevent the cursor jump when finger lifted */
     696 [ #  # ][ #  # ]:          0 :                 if (x == 0x7F && y == 0x7F && z == 0x7F)
     697                 :            :                         x = y = z = 0;
     698                 :            : 
     699                 :            :                 /* Divide 4 since trackpoint's speed is too fast */
     700                 :          0 :                 input_report_rel(dev2, REL_X, (char)x / 4);
     701                 :          0 :                 input_report_rel(dev2, REL_Y, -((char)y / 4));
     702                 :            : 
     703                 :            :                 input_report_key(dev2, BTN_LEFT, left);
     704                 :            :                 input_report_key(dev2, BTN_RIGHT, right);
     705                 :            :                 input_report_key(dev2, BTN_MIDDLE, middle);
     706                 :            : 
     707                 :            :                 input_sync(dev2);
     708                 :            :                 return;
     709                 :            :         }
     710                 :            : 
     711                 :            :         /* Touchpad packet */
     712                 :          0 :         x = packet[1] | ((packet[3] & 0x78) << 4);
     713                 :          0 :         y = packet[2] | ((packet[4] & 0x78) << 4);
     714                 :          0 :         z = packet[5];
     715                 :          0 :         left = packet[3] & 0x01;
     716                 :          0 :         right = packet[3] & 0x02;
     717                 :            : 
     718         [ #  # ]:          0 :         if (z > 30)
     719                 :            :                 input_report_key(dev, BTN_TOUCH, 1);
     720         [ #  # ]:          0 :         if (z < 25)
     721                 :            :                 input_report_key(dev, BTN_TOUCH, 0);
     722                 :            : 
     723         [ #  # ]:          0 :         if (z > 0) {
     724                 :            :                 input_report_abs(dev, ABS_X, x);
     725                 :            :                 input_report_abs(dev, ABS_Y, y);
     726                 :            :         }
     727                 :            : 
     728                 :            :         input_report_abs(dev, ABS_PRESSURE, z);
     729                 :          0 :         input_report_key(dev, BTN_TOOL_FINGER, z > 0);
     730                 :            : 
     731                 :            :         /* v6 touchpad does not have middle button */
     732                 :            :         input_report_key(dev, BTN_LEFT, left);
     733                 :            :         input_report_key(dev, BTN_RIGHT, right);
     734                 :            : 
     735                 :            :         input_sync(dev);
     736                 :            : }
     737                 :            : 
     738                 :          0 : static void alps_process_packet_v4(struct psmouse *psmouse)
     739                 :            : {
     740                 :          0 :         struct alps_data *priv = psmouse->private;
     741                 :            :         unsigned char *packet = psmouse->packet;
     742                 :          0 :         struct input_dev *dev = psmouse->dev;
     743                 :            :         int offset;
     744                 :            :         int x, y, z;
     745                 :            :         int left, right;
     746                 :            :         int x1, y1, x2, y2;
     747                 :            :         int fingers = 0;
     748                 :            :         unsigned int x_bitmap, y_bitmap;
     749                 :            : 
     750                 :            :         /*
     751                 :            :          * v4 has a 6-byte encoding for bitmap data, but this data is
     752                 :            :          * broken up between 3 normal packets. Use priv->multi_packet to
     753                 :            :          * track our position in the bitmap packet.
     754                 :            :          */
     755         [ #  # ]:          0 :         if (packet[6] & 0x40) {
     756                 :            :                 /* sync, reset position */
     757                 :          0 :                 priv->multi_packet = 0;
     758                 :            :         }
     759                 :            : 
     760 [ #  # ][ #  # ]:          0 :         if (WARN_ON_ONCE(priv->multi_packet > 2))
         [ #  # ][ #  # ]
     761                 :          0 :                 return;
     762                 :            : 
     763                 :          0 :         offset = 2 * priv->multi_packet;
     764                 :          0 :         priv->multi_data[offset] = packet[6];
     765                 :          0 :         priv->multi_data[offset + 1] = packet[7];
     766                 :            : 
     767         [ #  # ]:          0 :         if (++priv->multi_packet > 2) {
     768                 :          0 :                 priv->multi_packet = 0;
     769                 :            : 
     770                 :          0 :                 x_bitmap = ((priv->multi_data[2] & 0x1f) << 10) |
     771                 :          0 :                            ((priv->multi_data[3] & 0x60) << 3) |
     772                 :          0 :                            ((priv->multi_data[0] & 0x3f) << 2) |
     773                 :          0 :                            ((priv->multi_data[1] & 0x60) >> 5);
     774                 :          0 :                 y_bitmap = ((priv->multi_data[5] & 0x01) << 10) |
     775                 :          0 :                            ((priv->multi_data[3] & 0x1f) << 5) |
     776                 :          0 :                             (priv->multi_data[1] & 0x1f);
     777                 :            : 
     778                 :          0 :                 fingers = alps_process_bitmap(priv, x_bitmap, y_bitmap,
     779                 :            :                                               &x1, &y1, &x2, &y2);
     780                 :            : 
     781                 :            :                 /* Store MT data.*/
     782                 :          0 :                 priv->fingers = fingers;
     783                 :          0 :                 priv->x1 = x1;
     784                 :          0 :                 priv->x2 = x2;
     785                 :          0 :                 priv->y1 = y1;
     786                 :          0 :                 priv->y2 = y2;
     787                 :            :         }
     788                 :            : 
     789                 :          0 :         left = packet[4] & 0x01;
     790                 :          0 :         right = packet[4] & 0x02;
     791                 :            : 
     792                 :          0 :         x = ((packet[1] & 0x7f) << 4) | ((packet[3] & 0x30) >> 2) |
     793                 :          0 :             ((packet[0] & 0x30) >> 4);
     794                 :          0 :         y = ((packet[2] & 0x7f) << 4) | (packet[3] & 0x0f);
     795                 :          0 :         z = packet[5] & 0x7f;
     796                 :            : 
     797                 :            :         /*
     798                 :            :          * If there were no contacts in the bitmap, use ST
     799                 :            :          * points in MT reports.
     800                 :            :          * If there were two contacts or more, report MT data.
     801                 :            :          */
     802         [ #  # ]:          0 :         if (priv->fingers < 2) {
     803                 :          0 :                 x1 = x;
     804                 :          0 :                 y1 = y;
     805                 :          0 :                 fingers = z > 0 ? 1 : 0;
     806                 :            :         } else {
     807                 :            :                 fingers = priv->fingers;
     808                 :          0 :                 x1 = priv->x1;
     809                 :          0 :                 x2 = priv->x2;
     810                 :          0 :                 y1 = priv->y1;
     811                 :          0 :                 y2 = priv->y2;
     812                 :            :         }
     813                 :            : 
     814         [ #  # ]:          0 :         if (z >= 64)
     815                 :            :                 input_report_key(dev, BTN_TOUCH, 1);
     816                 :            :         else
     817                 :            :                 input_report_key(dev, BTN_TOUCH, 0);
     818                 :            : 
     819                 :          0 :         alps_report_semi_mt_data(dev, fingers, x1, y1, x2, y2);
     820                 :            : 
     821                 :          0 :         input_mt_report_finger_count(dev, fingers);
     822                 :            : 
     823                 :            :         input_report_key(dev, BTN_LEFT, left);
     824                 :            :         input_report_key(dev, BTN_RIGHT, right);
     825                 :            : 
     826         [ #  # ]:          0 :         if (z > 0) {
     827                 :            :                 input_report_abs(dev, ABS_X, x);
     828                 :            :                 input_report_abs(dev, ABS_Y, y);
     829                 :            :         }
     830                 :            :         input_report_abs(dev, ABS_PRESSURE, z);
     831                 :            : 
     832                 :            :         input_sync(dev);
     833                 :            : }
     834                 :            : 
     835                 :          0 : static void alps_report_bare_ps2_packet(struct psmouse *psmouse,
     836                 :            :                                         unsigned char packet[],
     837                 :            :                                         bool report_buttons)
     838                 :            : {
     839                 :          0 :         struct alps_data *priv = psmouse->private;
     840                 :          0 :         struct input_dev *dev2 = priv->dev2;
     841                 :            : 
     842         [ #  # ]:          0 :         if (report_buttons)
     843                 :          0 :                 alps_report_buttons(psmouse, dev2, psmouse->dev,
     844                 :          0 :                                 packet[0] & 1, packet[0] & 2, packet[0] & 4);
     845                 :            : 
     846         [ #  # ]:          0 :         input_report_rel(dev2, REL_X,
     847                 :          0 :                 packet[1] ? packet[1] - ((packet[0] << 4) & 0x100) : 0);
     848         [ #  # ]:          0 :         input_report_rel(dev2, REL_Y,
     849                 :          0 :                 packet[2] ? ((packet[0] << 3) & 0x100) - packet[2] : 0);
     850                 :            : 
     851                 :            :         input_sync(dev2);
     852                 :          0 : }
     853                 :            : 
     854                 :          0 : static psmouse_ret_t alps_handle_interleaved_ps2(struct psmouse *psmouse)
     855                 :            : {
     856                 :          0 :         struct alps_data *priv = psmouse->private;
     857                 :            : 
     858         [ #  # ]:          0 :         if (psmouse->pktcnt < 6)
     859                 :            :                 return PSMOUSE_GOOD_DATA;
     860                 :            : 
     861         [ #  # ]:          0 :         if (psmouse->pktcnt == 6) {
     862                 :            :                 /*
     863                 :            :                  * Start a timer to flush the packet if it ends up last
     864                 :            :                  * 6-byte packet in the stream. Timer needs to fire
     865                 :            :                  * psmouse core times out itself. 20 ms should be enough
     866                 :            :                  * to decide if we are getting more data or not.
     867                 :            :                  */
     868                 :          0 :                 mod_timer(&priv->timer, jiffies + msecs_to_jiffies(20));
     869                 :          0 :                 return PSMOUSE_GOOD_DATA;
     870                 :            :         }
     871                 :            : 
     872                 :          0 :         del_timer(&priv->timer);
     873                 :            : 
     874         [ #  # ]:          0 :         if (psmouse->packet[6] & 0x80) {
     875                 :            : 
     876                 :            :                 /*
     877                 :            :                  * Highest bit is set - that means we either had
     878                 :            :                  * complete ALPS packet and this is start of the
     879                 :            :                  * next packet or we got garbage.
     880                 :            :                  */
     881                 :            : 
     882         [ #  # ]:          0 :                 if (((psmouse->packet[3] |
     883                 :          0 :                       psmouse->packet[4] |
     884         [ #  # ]:          0 :                       psmouse->packet[5]) & 0x80) ||
     885                 :            :                     (!alps_is_valid_first_byte(priv, psmouse->packet[6]))) {
     886                 :            :                         psmouse_dbg(psmouse,
     887                 :            :                                     "refusing packet %4ph (suspected interleaved ps/2)\n",
     888                 :            :                                     psmouse->packet + 3);
     889                 :            :                         return PSMOUSE_BAD_DATA;
     890                 :            :                 }
     891                 :            : 
     892                 :          0 :                 priv->process_packet(psmouse);
     893                 :            : 
     894                 :            :                 /* Continue with the next packet */
     895                 :          0 :                 psmouse->packet[0] = psmouse->packet[6];
     896                 :          0 :                 psmouse->pktcnt = 1;
     897                 :            : 
     898                 :            :         } else {
     899                 :            : 
     900                 :            :                 /*
     901                 :            :                  * High bit is 0 - that means that we indeed got a PS/2
     902                 :            :                  * packet in the middle of ALPS packet.
     903                 :            :                  *
     904                 :            :                  * There is also possibility that we got 6-byte ALPS
     905                 :            :                  * packet followed  by 3-byte packet from trackpoint. We
     906                 :            :                  * can not distinguish between these 2 scenarios but
     907                 :            :                  * because the latter is unlikely to happen in course of
     908                 :            :                  * normal operation (user would need to press all
     909                 :            :                  * buttons on the pad and start moving trackpoint
     910                 :            :                  * without touching the pad surface) we assume former.
     911                 :            :                  * Even if we are wrong the wost thing that would happen
     912                 :            :                  * the cursor would jump but we should not get protocol
     913                 :            :                  * de-synchronization.
     914                 :            :                  */
     915                 :            : 
     916                 :          0 :                 alps_report_bare_ps2_packet(psmouse, &psmouse->packet[3],
     917                 :            :                                             false);
     918                 :            : 
     919                 :            :                 /*
     920                 :            :                  * Continue with the standard ALPS protocol handling,
     921                 :            :                  * but make sure we won't process it as an interleaved
     922                 :            :                  * packet again, which may happen if all buttons are
     923                 :            :                  * pressed. To avoid this let's reset the 4th bit which
     924                 :            :                  * is normally 1.
     925                 :            :                  */
     926                 :          0 :                 psmouse->packet[3] = psmouse->packet[6] & 0xf7;
     927                 :          0 :                 psmouse->pktcnt = 4;
     928                 :            :         }
     929                 :            : 
     930                 :            :         return PSMOUSE_GOOD_DATA;
     931                 :            : }
     932                 :            : 
     933                 :          0 : static void alps_flush_packet(unsigned long data)
     934                 :            : {
     935                 :          0 :         struct psmouse *psmouse = (struct psmouse *)data;
     936                 :          0 :         struct alps_data *priv = psmouse->private;
     937                 :            : 
     938                 :          0 :         serio_pause_rx(psmouse->ps2dev.serio);
     939                 :            : 
     940         [ #  # ]:          0 :         if (psmouse->pktcnt == psmouse->pktsize) {
     941                 :            : 
     942                 :            :                 /*
     943                 :            :                  * We did not any more data in reasonable amount of time.
     944                 :            :                  * Validate the last 3 bytes and process as a standard
     945                 :            :                  * ALPS packet.
     946                 :            :                  */
     947         [ #  # ]:          0 :                 if ((psmouse->packet[3] |
     948                 :          0 :                      psmouse->packet[4] |
     949                 :          0 :                      psmouse->packet[5]) & 0x80) {
     950                 :            :                         psmouse_dbg(psmouse,
     951                 :            :                                     "refusing packet %3ph (suspected interleaved ps/2)\n",
     952                 :            :                                     psmouse->packet + 3);
     953                 :            :                 } else {
     954                 :          0 :                         priv->process_packet(psmouse);
     955                 :            :                 }
     956                 :          0 :                 psmouse->pktcnt = 0;
     957                 :            :         }
     958                 :            : 
     959                 :          0 :         serio_continue_rx(psmouse->ps2dev.serio);
     960                 :          0 : }
     961                 :            : 
     962                 :          0 : static psmouse_ret_t alps_process_byte(struct psmouse *psmouse)
     963                 :            : {
     964                 :          0 :         struct alps_data *priv = psmouse->private;
     965                 :            : 
     966         [ #  # ]:          0 :         if ((psmouse->packet[0] & 0xc8) == 0x08) { /* PS/2 packet */
     967         [ #  # ]:          0 :                 if (psmouse->pktcnt == 3) {
     968                 :          0 :                         alps_report_bare_ps2_packet(psmouse, psmouse->packet,
     969                 :            :                                                     true);
     970                 :          0 :                         return PSMOUSE_FULL_PACKET;
     971                 :            :                 }
     972                 :            :                 return PSMOUSE_GOOD_DATA;
     973                 :            :         }
     974                 :            : 
     975                 :            :         /* Check for PS/2 packet stuffed in the middle of ALPS packet. */
     976                 :            : 
     977 [ #  # ][ #  # ]:          0 :         if ((priv->flags & ALPS_PS2_INTERLEAVED) &&
     978         [ #  # ]:          0 :             psmouse->pktcnt >= 4 && (psmouse->packet[3] & 0x0f) == 0x0f) {
     979                 :          0 :                 return alps_handle_interleaved_ps2(psmouse);
     980                 :            :         }
     981                 :            : 
     982         [ #  # ]:          0 :         if (!alps_is_valid_first_byte(priv, psmouse->packet[0])) {
     983                 :            :                 psmouse_dbg(psmouse,
     984                 :            :                             "refusing packet[0] = %x (mask0 = %x, byte0 = %x)\n",
     985                 :            :                             psmouse->packet[0], priv->mask0, priv->byte0);
     986                 :            :                 return PSMOUSE_BAD_DATA;
     987                 :            :         }
     988                 :            : 
     989                 :            :         /* Bytes 2 - pktsize should have 0 in the highest bit */
     990 [ #  # ][ #  # ]:          0 :         if ((priv->proto_version < ALPS_PROTO_V5) &&
     991 [ #  # ][ #  # ]:          0 :             psmouse->pktcnt >= 2 && psmouse->pktcnt <= psmouse->pktsize &&
     992                 :          0 :             (psmouse->packet[psmouse->pktcnt - 1] & 0x80)) {
     993                 :            :                 psmouse_dbg(psmouse, "refusing packet[%i] = %x\n",
     994                 :            :                             psmouse->pktcnt - 1,
     995                 :            :                             psmouse->packet[psmouse->pktcnt - 1]);
     996                 :            :                 return PSMOUSE_BAD_DATA;
     997                 :            :         }
     998                 :            : 
     999         [ #  # ]:          0 :         if (psmouse->pktcnt == psmouse->pktsize) {
    1000                 :          0 :                 priv->process_packet(psmouse);
    1001                 :          0 :                 return PSMOUSE_FULL_PACKET;
    1002                 :            :         }
    1003                 :            : 
    1004                 :            :         return PSMOUSE_GOOD_DATA;
    1005                 :            : }
    1006                 :            : 
    1007                 :          0 : static int alps_command_mode_send_nibble(struct psmouse *psmouse, int nibble)
    1008                 :            : {
    1009                 :          0 :         struct ps2dev *ps2dev = &psmouse->ps2dev;
    1010                 :          0 :         struct alps_data *priv = psmouse->private;
    1011                 :            :         int command;
    1012                 :            :         unsigned char *param;
    1013                 :            :         unsigned char dummy[4];
    1014                 :            : 
    1015         [ #  # ]:          0 :         BUG_ON(nibble > 0xf);
    1016                 :            : 
    1017                 :          0 :         command = priv->nibble_commands[nibble].command;
    1018                 :          0 :         param = (command & 0x0f00) ?
    1019         [ #  # ]:          0 :                 dummy : (unsigned char *)&priv->nibble_commands[nibble].data;
    1020                 :            : 
    1021         [ #  # ]:          0 :         if (ps2_command(ps2dev, param, command))
    1022                 :            :                 return -1;
    1023                 :            : 
    1024                 :          0 :         return 0;
    1025                 :            : }
    1026                 :            : 
    1027                 :          0 : static int alps_command_mode_set_addr(struct psmouse *psmouse, int addr)
    1028                 :            : {
    1029                 :          0 :         struct ps2dev *ps2dev = &psmouse->ps2dev;
    1030                 :          0 :         struct alps_data *priv = psmouse->private;
    1031                 :            :         int i, nibble;
    1032                 :            : 
    1033         [ #  # ]:          0 :         if (ps2_command(ps2dev, NULL, priv->addr_command))
    1034                 :            :                 return -1;
    1035                 :            : 
    1036         [ #  # ]:          0 :         for (i = 12; i >= 0; i -= 4) {
    1037                 :          0 :                 nibble = (addr >> i) & 0xf;
    1038         [ #  # ]:          0 :                 if (alps_command_mode_send_nibble(psmouse, nibble))
    1039                 :            :                         return -1;
    1040                 :            :         }
    1041                 :            : 
    1042                 :            :         return 0;
    1043                 :            : }
    1044                 :            : 
    1045                 :          0 : static int __alps_command_mode_read_reg(struct psmouse *psmouse, int addr)
    1046                 :            : {
    1047                 :          0 :         struct ps2dev *ps2dev = &psmouse->ps2dev;
    1048                 :            :         unsigned char param[4];
    1049                 :            : 
    1050         [ #  # ]:          0 :         if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO))
    1051                 :            :                 return -1;
    1052                 :            : 
    1053                 :            :         /*
    1054                 :            :          * The address being read is returned in the first two bytes
    1055                 :            :          * of the result. Check that this address matches the expected
    1056                 :            :          * address.
    1057                 :            :          */
    1058         [ #  # ]:          0 :         if (addr != ((param[0] << 8) | param[1]))
    1059                 :            :                 return -1;
    1060                 :            : 
    1061                 :          0 :         return param[2];
    1062                 :            : }
    1063                 :            : 
    1064                 :          0 : static int alps_command_mode_read_reg(struct psmouse *psmouse, int addr)
    1065                 :            : {
    1066         [ #  # ]:          0 :         if (alps_command_mode_set_addr(psmouse, addr))
    1067                 :            :                 return -1;
    1068                 :          0 :         return __alps_command_mode_read_reg(psmouse, addr);
    1069                 :            : }
    1070                 :            : 
    1071                 :          0 : static int __alps_command_mode_write_reg(struct psmouse *psmouse, u8 value)
    1072                 :            : {
    1073         [ #  # ]:          0 :         if (alps_command_mode_send_nibble(psmouse, (value >> 4) & 0xf))
    1074                 :            :                 return -1;
    1075         [ #  # ]:          0 :         if (alps_command_mode_send_nibble(psmouse, value & 0xf))
    1076                 :            :                 return -1;
    1077                 :          0 :         return 0;
    1078                 :            : }
    1079                 :            : 
    1080                 :          0 : static int alps_command_mode_write_reg(struct psmouse *psmouse, int addr,
    1081                 :            :                                        u8 value)
    1082                 :            : {
    1083         [ #  # ]:          0 :         if (alps_command_mode_set_addr(psmouse, addr))
    1084                 :            :                 return -1;
    1085                 :          0 :         return __alps_command_mode_write_reg(psmouse, value);
    1086                 :            : }
    1087                 :            : 
    1088                 :          0 : static int alps_rpt_cmd(struct psmouse *psmouse, int init_command,
    1089                 :            :                         int repeated_command, unsigned char *param)
    1090                 :            : {
    1091                 :          0 :         struct ps2dev *ps2dev = &psmouse->ps2dev;
    1092                 :            : 
    1093                 :          0 :         param[0] = 0;
    1094 [ #  # ][ #  # ]:          0 :         if (init_command && ps2_command(ps2dev, param, init_command))
    1095                 :            :                 return -EIO;
    1096                 :            : 
    1097   [ #  #  #  # ]:          0 :         if (ps2_command(ps2dev,  NULL, repeated_command) ||
    1098         [ #  # ]:          0 :             ps2_command(ps2dev,  NULL, repeated_command) ||
    1099                 :          0 :             ps2_command(ps2dev,  NULL, repeated_command))
    1100                 :            :                 return -EIO;
    1101                 :            : 
    1102                 :          0 :         param[0] = param[1] = param[2] = 0xff;
    1103         [ #  # ]:          0 :         if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO))
    1104                 :            :                 return -EIO;
    1105                 :            : 
    1106                 :            :         psmouse_dbg(psmouse, "%2.2X report: %3ph\n",
    1107                 :            :                     repeated_command, param);
    1108                 :          0 :         return 0;
    1109                 :            : }
    1110                 :            : 
    1111                 :          0 : static int alps_enter_command_mode(struct psmouse *psmouse)
    1112                 :            : {
    1113                 :            :         unsigned char param[4];
    1114                 :            : 
    1115         [ #  # ]:          0 :         if (alps_rpt_cmd(psmouse, 0, PSMOUSE_CMD_RESET_WRAP, param)) {
    1116                 :          0 :                 psmouse_err(psmouse, "failed to enter command mode\n");
    1117                 :          0 :                 return -1;
    1118                 :            :         }
    1119                 :            : 
    1120 [ #  # ][ #  # ]:          0 :         if ((param[0] != 0x88 || (param[1] != 0x07 && param[1] != 0x08)) &&
                 [ #  # ]
    1121                 :            :             param[0] != 0x73) {
    1122                 :            :                 psmouse_dbg(psmouse,
    1123                 :            :                             "unknown response while entering command mode\n");
    1124                 :            :                 return -1;
    1125                 :            :         }
    1126                 :          0 :         return 0;
    1127                 :            : }
    1128                 :            : 
    1129                 :            : static inline int alps_exit_command_mode(struct psmouse *psmouse)
    1130                 :            : {
    1131                 :          0 :         struct ps2dev *ps2dev = &psmouse->ps2dev;
    1132 [ #  # ][ #  # ]:          0 :         if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSTREAM))
                 [ #  # ]
    1133                 :            :                 return -1;
    1134                 :            :         return 0;
    1135                 :            : }
    1136                 :            : 
    1137                 :            : /*
    1138                 :            :  * For DualPoint devices select the device that should respond to
    1139                 :            :  * subsequent commands. It looks like glidepad is behind stickpointer,
    1140                 :            :  * I'd thought it would be other way around...
    1141                 :            :  */
    1142                 :          0 : static int alps_passthrough_mode_v2(struct psmouse *psmouse, bool enable)
    1143                 :            : {
    1144                 :          0 :         struct ps2dev *ps2dev = &psmouse->ps2dev;
    1145         [ #  # ]:          0 :         int cmd = enable ? PSMOUSE_CMD_SETSCALE21 : PSMOUSE_CMD_SETSCALE11;
    1146                 :            : 
    1147   [ #  #  #  # ]:          0 :         if (ps2_command(ps2dev, NULL, cmd) ||
    1148         [ #  # ]:          0 :             ps2_command(ps2dev, NULL, cmd) ||
    1149         [ #  # ]:          0 :             ps2_command(ps2dev, NULL, cmd) ||
    1150                 :          0 :             ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE))
    1151                 :            :                 return -1;
    1152                 :            : 
    1153                 :            :         /* we may get 3 more bytes, just ignore them */
    1154                 :          0 :         ps2_drain(ps2dev, 3, 100);
    1155                 :            : 
    1156                 :          0 :         return 0;
    1157                 :            : }
    1158                 :            : 
    1159                 :          0 : static int alps_absolute_mode_v1_v2(struct psmouse *psmouse)
    1160                 :            : {
    1161                 :          0 :         struct ps2dev *ps2dev = &psmouse->ps2dev;
    1162                 :            : 
    1163                 :            :         /* Try ALPS magic knock - 4 disable before enable */
    1164   [ #  #  #  # ]:          0 :         if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
    1165         [ #  # ]:          0 :             ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
    1166         [ #  # ]:          0 :             ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
    1167         [ #  # ]:          0 :             ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
    1168                 :          0 :             ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE))
    1169                 :            :                 return -1;
    1170                 :            : 
    1171                 :            :         /*
    1172                 :            :          * Switch mouse to poll (remote) mode so motion data will not
    1173                 :            :          * get in our way
    1174                 :            :          */
    1175                 :          0 :         return ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETPOLL);
    1176                 :            : }
    1177                 :            : 
    1178                 :          0 : static int alps_monitor_mode_send_word(struct psmouse *psmouse, u16 word)
    1179                 :            : {
    1180                 :            :         int i, nibble;
    1181                 :            : 
    1182                 :            :         /*
    1183                 :            :          * b0-b11 are valid bits, send sequence is inverse.
    1184                 :            :          * e.g. when word = 0x0123, nibble send sequence is 3, 2, 1
    1185                 :            :          */
    1186         [ #  # ]:          0 :         for (i = 0; i <= 8; i += 4) {
    1187                 :          0 :                 nibble = (word >> i) & 0xf;
    1188         [ #  # ]:          0 :                 if (alps_command_mode_send_nibble(psmouse, nibble))
    1189                 :            :                         return -1;
    1190                 :            :         }
    1191                 :            : 
    1192                 :            :         return 0;
    1193                 :            : }
    1194                 :            : 
    1195                 :          0 : static int alps_monitor_mode_write_reg(struct psmouse *psmouse,
    1196                 :            :                                        u16 addr, u16 value)
    1197                 :            : {
    1198                 :          0 :         struct ps2dev *ps2dev = &psmouse->ps2dev;
    1199                 :            : 
    1200                 :            :         /* 0x0A0 is the command to write the word */
    1201   [ #  #  #  # ]:          0 :         if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE) ||
    1202         [ #  # ]:          0 :             alps_monitor_mode_send_word(psmouse, 0x0A0) ||
    1203         [ #  # ]:          0 :             alps_monitor_mode_send_word(psmouse, addr) ||
    1204         [ #  # ]:          0 :             alps_monitor_mode_send_word(psmouse, value) ||
    1205                 :          0 :             ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE))
    1206                 :            :                 return -1;
    1207                 :            : 
    1208                 :            :         return 0;
    1209                 :            : }
    1210                 :            : 
    1211                 :          0 : static int alps_monitor_mode(struct psmouse *psmouse, bool enable)
    1212                 :            : {
    1213                 :          0 :         struct ps2dev *ps2dev = &psmouse->ps2dev;
    1214                 :            : 
    1215         [ #  # ]:          0 :         if (enable) {
    1216                 :            :                 /* EC E9 F5 F5 E7 E6 E7 E9 to enter monitor mode */
    1217   [ #  #  #  # ]:          0 :                 if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_WRAP) ||
    1218         [ #  # ]:          0 :                     ps2_command(ps2dev, NULL, PSMOUSE_CMD_GETINFO) ||
    1219         [ #  # ]:          0 :                     ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
    1220         [ #  # ]:          0 :                     ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
    1221         [ #  # ]:          0 :                     ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) ||
    1222         [ #  # ]:          0 :                     ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) ||
    1223         [ #  # ]:          0 :                     ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) ||
    1224                 :          0 :                     ps2_command(ps2dev, NULL, PSMOUSE_CMD_GETINFO))
    1225                 :            :                         return -1;
    1226                 :            :         } else {
    1227                 :            :                 /* EC to exit monitor mode */
    1228         [ #  # ]:          0 :                 if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_WRAP))
    1229                 :            :                         return -1;
    1230                 :            :         }
    1231                 :            : 
    1232                 :            :         return 0;
    1233                 :            : }
    1234                 :            : 
    1235                 :          0 : static int alps_absolute_mode_v6(struct psmouse *psmouse)
    1236                 :            : {
    1237                 :            :         u16 reg_val = 0x181;
    1238                 :            :         int ret = -1;
    1239                 :            : 
    1240                 :            :         /* enter monitor mode, to write the register */
    1241         [ #  # ]:          0 :         if (alps_monitor_mode(psmouse, true))
    1242                 :            :                 return -1;
    1243                 :            : 
    1244                 :          0 :         ret = alps_monitor_mode_write_reg(psmouse, 0x000, reg_val);
    1245                 :            : 
    1246         [ #  # ]:          0 :         if (alps_monitor_mode(psmouse, false))
    1247                 :            :                 ret = -1;
    1248                 :            : 
    1249                 :          0 :         return ret;
    1250                 :            : }
    1251                 :            : 
    1252                 :            : static int alps_get_status(struct psmouse *psmouse, char *param)
    1253                 :            : {
    1254                 :            :         /* Get status: 0xF5 0xF5 0xF5 0xE9 */
    1255         [ #  # ]:          0 :         if (alps_rpt_cmd(psmouse, 0, PSMOUSE_CMD_DISABLE, param))
    1256                 :            :                 return -1;
    1257                 :            : 
    1258                 :            :         return 0;
    1259                 :            : }
    1260                 :            : 
    1261                 :            : /*
    1262                 :            :  * Turn touchpad tapping on or off. The sequences are:
    1263                 :            :  * 0xE9 0xF5 0xF5 0xF3 0x0A to enable,
    1264                 :            :  * 0xE9 0xF5 0xF5 0xE8 0x00 to disable.
    1265                 :            :  * My guess that 0xE9 (GetInfo) is here as a sync point.
    1266                 :            :  * For models that also have stickpointer (DualPoints) its tapping
    1267                 :            :  * is controlled separately (0xE6 0xE6 0xE6 0xF3 0x14|0x0A) but
    1268                 :            :  * we don't fiddle with it.
    1269                 :            :  */
    1270                 :          0 : static int alps_tap_mode(struct psmouse *psmouse, int enable)
    1271                 :            : {
    1272                 :          0 :         struct ps2dev *ps2dev = &psmouse->ps2dev;
    1273         [ #  # ]:          0 :         int cmd = enable ? PSMOUSE_CMD_SETRATE : PSMOUSE_CMD_SETRES;
    1274         [ #  # ]:          0 :         unsigned char tap_arg = enable ? 0x0A : 0x00;
    1275                 :            :         unsigned char param[4];
    1276                 :            : 
    1277   [ #  #  #  # ]:          0 :         if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO) ||
    1278         [ #  # ]:          0 :             ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
    1279         [ #  # ]:          0 :             ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
    1280                 :          0 :             ps2_command(ps2dev, &tap_arg, cmd))
    1281                 :            :                 return -1;
    1282                 :            : 
    1283         [ #  # ]:          0 :         if (alps_get_status(psmouse, param))
    1284                 :            :                 return -1;
    1285                 :            : 
    1286                 :          0 :         return 0;
    1287                 :            : }
    1288                 :            : 
    1289                 :            : /*
    1290                 :            :  * alps_poll() - poll the touchpad for current motion packet.
    1291                 :            :  * Used in resync.
    1292                 :            :  */
    1293                 :          0 : static int alps_poll(struct psmouse *psmouse)
    1294                 :            : {
    1295                 :          0 :         struct alps_data *priv = psmouse->private;
    1296                 :            :         unsigned char buf[sizeof(psmouse->packet)];
    1297                 :            :         bool poll_failed;
    1298                 :            : 
    1299         [ #  # ]:          0 :         if (priv->flags & ALPS_PASS)
    1300                 :          0 :                 alps_passthrough_mode_v2(psmouse, true);
    1301                 :            : 
    1302                 :          0 :         poll_failed = ps2_command(&psmouse->ps2dev, buf,
    1303                 :          0 :                                   PSMOUSE_CMD_POLL | (psmouse->pktsize << 8)) < 0;
    1304                 :            : 
    1305         [ #  # ]:          0 :         if (priv->flags & ALPS_PASS)
    1306                 :          0 :                 alps_passthrough_mode_v2(psmouse, false);
    1307                 :            : 
    1308 [ #  # ][ #  # ]:          0 :         if (poll_failed || (buf[0] & priv->mask0) != priv->byte0)
    1309                 :            :                 return -1;
    1310                 :            : 
    1311         [ #  # ]:          0 :         if ((psmouse->badbyte & 0xc8) == 0x08) {
    1312                 :            : /*
    1313                 :            :  * Poll the track stick ...
    1314                 :            :  */
    1315         [ #  # ]:          0 :                 if (ps2_command(&psmouse->ps2dev, buf, PSMOUSE_CMD_POLL | (3 << 8)))
    1316                 :            :                         return -1;
    1317                 :            :         }
    1318                 :            : 
    1319                 :          0 :         memcpy(psmouse->packet, buf, sizeof(buf));
    1320                 :          0 :         return 0;
    1321                 :            : }
    1322                 :            : 
    1323                 :          0 : static int alps_hw_init_v1_v2(struct psmouse *psmouse)
    1324                 :            : {
    1325                 :          0 :         struct alps_data *priv = psmouse->private;
    1326                 :            : 
    1327   [ #  #  #  # ]:          0 :         if ((priv->flags & ALPS_PASS) &&
    1328                 :          0 :             alps_passthrough_mode_v2(psmouse, true)) {
    1329                 :            :                 return -1;
    1330                 :            :         }
    1331                 :            : 
    1332         [ #  # ]:          0 :         if (alps_tap_mode(psmouse, true)) {
    1333                 :          0 :                 psmouse_warn(psmouse, "Failed to enable hardware tapping\n");
    1334                 :          0 :                 return -1;
    1335                 :            :         }
    1336                 :            : 
    1337         [ #  # ]:          0 :         if (alps_absolute_mode_v1_v2(psmouse)) {
    1338                 :          0 :                 psmouse_err(psmouse, "Failed to enable absolute mode\n");
    1339                 :          0 :                 return -1;
    1340                 :            :         }
    1341                 :            : 
    1342   [ #  #  #  # ]:          0 :         if ((priv->flags & ALPS_PASS) &&
    1343                 :          0 :             alps_passthrough_mode_v2(psmouse, false)) {
    1344                 :            :                 return -1;
    1345                 :            :         }
    1346                 :            : 
    1347                 :            :         /* ALPS needs stream mode, otherwise it won't report any data */
    1348         [ #  # ]:          0 :         if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSTREAM)) {
    1349                 :          0 :                 psmouse_err(psmouse, "Failed to enable stream mode\n");
    1350                 :          0 :                 return -1;
    1351                 :            :         }
    1352                 :            : 
    1353                 :            :         return 0;
    1354                 :            : }
    1355                 :            : 
    1356                 :          0 : static int alps_hw_init_v6(struct psmouse *psmouse)
    1357                 :            : {
    1358                 :          0 :         unsigned char param[2] = {0xC8, 0x14};
    1359                 :            : 
    1360                 :            :         /* Enter passthrough mode to let trackpoint enter 6byte raw mode */
    1361         [ #  # ]:          0 :         if (alps_passthrough_mode_v2(psmouse, true))
    1362                 :            :                 return -1;
    1363                 :            : 
    1364   [ #  #  #  # ]:          0 :         if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) ||
    1365         [ #  # ]:          0 :             ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) ||
    1366         [ #  # ]:          0 :             ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) ||
    1367         [ #  # ]:          0 :             ps2_command(&psmouse->ps2dev, &param[0], PSMOUSE_CMD_SETRATE) ||
    1368                 :          0 :             ps2_command(&psmouse->ps2dev, &param[1], PSMOUSE_CMD_SETRATE))
    1369                 :            :                 return -1;
    1370                 :            : 
    1371         [ #  # ]:          0 :         if (alps_passthrough_mode_v2(psmouse, false))
    1372                 :            :                 return -1;
    1373                 :            : 
    1374         [ #  # ]:          0 :         if (alps_absolute_mode_v6(psmouse)) {
    1375                 :          0 :                 psmouse_err(psmouse, "Failed to enable absolute mode\n");
    1376                 :          0 :                 return -1;
    1377                 :            :         }
    1378                 :            : 
    1379                 :            :         return 0;
    1380                 :            : }
    1381                 :            : 
    1382                 :            : /*
    1383                 :            :  * Enable or disable passthrough mode to the trackstick.
    1384                 :            :  */
    1385                 :          0 : static int alps_passthrough_mode_v3(struct psmouse *psmouse,
    1386                 :            :                                     int reg_base, bool enable)
    1387                 :            : {
    1388                 :            :         int reg_val, ret = -1;
    1389                 :            : 
    1390         [ #  # ]:          0 :         if (alps_enter_command_mode(psmouse))
    1391                 :            :                 return -1;
    1392                 :            : 
    1393                 :          0 :         reg_val = alps_command_mode_read_reg(psmouse, reg_base + 0x0008);
    1394         [ #  # ]:          0 :         if (reg_val == -1)
    1395                 :            :                 goto error;
    1396                 :            : 
    1397         [ #  # ]:          0 :         if (enable)
    1398                 :          0 :                 reg_val |= 0x01;
    1399                 :            :         else
    1400                 :          0 :                 reg_val &= ~0x01;
    1401                 :            : 
    1402                 :          0 :         ret = __alps_command_mode_write_reg(psmouse, reg_val);
    1403                 :            : 
    1404                 :            : error:
    1405         [ #  # ]:          0 :         if (alps_exit_command_mode(psmouse))
    1406                 :            :                 ret = -1;
    1407                 :          0 :         return ret;
    1408                 :            : }
    1409                 :            : 
    1410                 :            : /* Must be in command mode when calling this function */
    1411                 :          0 : static int alps_absolute_mode_v3(struct psmouse *psmouse)
    1412                 :            : {
    1413                 :            :         int reg_val;
    1414                 :            : 
    1415                 :          0 :         reg_val = alps_command_mode_read_reg(psmouse, 0x0004);
    1416         [ #  # ]:          0 :         if (reg_val == -1)
    1417                 :            :                 return -1;
    1418                 :            : 
    1419                 :          0 :         reg_val |= 0x06;
    1420         [ #  # ]:          0 :         if (__alps_command_mode_write_reg(psmouse, reg_val))
    1421                 :            :                 return -1;
    1422                 :            : 
    1423                 :          0 :         return 0;
    1424                 :            : }
    1425                 :            : 
    1426                 :          0 : static int alps_probe_trackstick_v3(struct psmouse *psmouse, int reg_base)
    1427                 :            : {
    1428                 :            :         int ret = -EIO, reg_val;
    1429                 :            : 
    1430         [ #  # ]:          0 :         if (alps_enter_command_mode(psmouse))
    1431                 :            :                 goto error;
    1432                 :            : 
    1433                 :          0 :         reg_val = alps_command_mode_read_reg(psmouse, reg_base + 0x08);
    1434         [ #  # ]:          0 :         if (reg_val == -1)
    1435                 :            :                 goto error;
    1436                 :            : 
    1437                 :            :         /* bit 7: trackstick is present */
    1438         [ #  # ]:          0 :         ret = reg_val & 0x80 ? 0 : -ENODEV;
    1439                 :            : 
    1440                 :            : error:
    1441                 :            :         alps_exit_command_mode(psmouse);
    1442                 :          0 :         return ret;
    1443                 :            : }
    1444                 :            : 
    1445                 :          0 : static int alps_setup_trackstick_v3(struct psmouse *psmouse, int reg_base)
    1446                 :            : {
    1447                 :          0 :         struct ps2dev *ps2dev = &psmouse->ps2dev;
    1448                 :            :         int ret = 0;
    1449                 :            :         unsigned char param[4];
    1450                 :            : 
    1451         [ #  # ]:          0 :         if (alps_passthrough_mode_v3(psmouse, reg_base, true))
    1452                 :            :                 return -EIO;
    1453                 :            : 
    1454                 :            :         /*
    1455                 :            :          * E7 report for the trackstick
    1456                 :            :          *
    1457                 :            :          * There have been reports of failures to seem to trace back
    1458                 :            :          * to the above trackstick check failing. When these occur
    1459                 :            :          * this E7 report fails, so when that happens we continue
    1460                 :            :          * with the assumption that there isn't a trackstick after
    1461                 :            :          * all.
    1462                 :            :          */
    1463         [ #  # ]:          0 :         if (alps_rpt_cmd(psmouse, 0, PSMOUSE_CMD_SETSCALE21, param)) {
    1464                 :          0 :                 psmouse_warn(psmouse, "trackstick E7 report failed\n");
    1465                 :            :                 ret = -ENODEV;
    1466                 :            :         } else {
    1467                 :            :                 psmouse_dbg(psmouse, "trackstick E7 report: %3ph\n", param);
    1468                 :            : 
    1469                 :            :                 /*
    1470                 :            :                  * Not sure what this does, but it is absolutely
    1471                 :            :                  * essential. Without it, the touchpad does not
    1472                 :            :                  * work at all and the trackstick just emits normal
    1473                 :            :                  * PS/2 packets.
    1474                 :            :                  */
    1475   [ #  #  #  # ]:          0 :                 if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) ||
    1476         [ #  # ]:          0 :                     ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) ||
    1477         [ #  # ]:          0 :                     ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) ||
    1478         [ #  # ]:          0 :                     alps_command_mode_send_nibble(psmouse, 0x9) ||
    1479                 :          0 :                     alps_command_mode_send_nibble(psmouse, 0x4)) {
    1480                 :          0 :                         psmouse_err(psmouse,
    1481                 :            :                                     "Error sending magic E6 sequence\n");
    1482                 :            :                         ret = -EIO;
    1483                 :          0 :                         goto error;
    1484                 :            :                 }
    1485                 :            : 
    1486                 :            :                 /*
    1487                 :            :                  * This ensures the trackstick packets are in the format
    1488                 :            :                  * supported by this driver. If bit 1 isn't set the packet
    1489                 :            :                  * format is different.
    1490                 :            :                  */
    1491   [ #  #  #  # ]:          0 :                 if (alps_enter_command_mode(psmouse) ||
    1492                 :          0 :                     alps_command_mode_write_reg(psmouse,
    1493         [ #  # ]:          0 :                                                 reg_base + 0x08, 0x82) ||
    1494                 :            :                     alps_exit_command_mode(psmouse))
    1495                 :            :                         ret = -EIO;
    1496                 :            :         }
    1497                 :            : 
    1498                 :            : error:
    1499         [ #  # ]:          0 :         if (alps_passthrough_mode_v3(psmouse, reg_base, false))
    1500                 :            :                 ret = -EIO;
    1501                 :            : 
    1502                 :          0 :         return ret;
    1503                 :            : }
    1504                 :            : 
    1505                 :          0 : static int alps_hw_init_v3(struct psmouse *psmouse)
    1506                 :            : {
    1507                 :          0 :         struct ps2dev *ps2dev = &psmouse->ps2dev;
    1508                 :            :         int reg_val;
    1509                 :            :         unsigned char param[4];
    1510                 :            : 
    1511                 :          0 :         reg_val = alps_probe_trackstick_v3(psmouse, ALPS_REG_BASE_PINNACLE);
    1512         [ #  # ]:          0 :         if (reg_val == -EIO)
    1513                 :            :                 goto error;
    1514                 :            : 
    1515   [ #  #  #  # ]:          0 :         if (reg_val == 0 &&
    1516                 :          0 :             alps_setup_trackstick_v3(psmouse, ALPS_REG_BASE_PINNACLE) == -EIO)
    1517                 :            :                 goto error;
    1518                 :            : 
    1519   [ #  #  #  # ]:          0 :         if (alps_enter_command_mode(psmouse) ||
    1520                 :          0 :             alps_absolute_mode_v3(psmouse)) {
    1521                 :          0 :                 psmouse_err(psmouse, "Failed to enter absolute mode\n");
    1522                 :          0 :                 goto error;
    1523                 :            :         }
    1524                 :            : 
    1525                 :          0 :         reg_val = alps_command_mode_read_reg(psmouse, 0x0006);
    1526         [ #  # ]:          0 :         if (reg_val == -1)
    1527                 :            :                 goto error;
    1528         [ #  # ]:          0 :         if (__alps_command_mode_write_reg(psmouse, reg_val | 0x01))
    1529                 :            :                 goto error;
    1530                 :            : 
    1531                 :          0 :         reg_val = alps_command_mode_read_reg(psmouse, 0x0007);
    1532         [ #  # ]:          0 :         if (reg_val == -1)
    1533                 :            :                 goto error;
    1534         [ #  # ]:          0 :         if (__alps_command_mode_write_reg(psmouse, reg_val | 0x01))
    1535                 :            :                 goto error;
    1536                 :            : 
    1537         [ #  # ]:          0 :         if (alps_command_mode_read_reg(psmouse, 0x0144) == -1)
    1538                 :            :                 goto error;
    1539         [ #  # ]:          0 :         if (__alps_command_mode_write_reg(psmouse, 0x04))
    1540                 :            :                 goto error;
    1541                 :            : 
    1542         [ #  # ]:          0 :         if (alps_command_mode_read_reg(psmouse, 0x0159) == -1)
    1543                 :            :                 goto error;
    1544         [ #  # ]:          0 :         if (__alps_command_mode_write_reg(psmouse, 0x03))
    1545                 :            :                 goto error;
    1546                 :            : 
    1547         [ #  # ]:          0 :         if (alps_command_mode_read_reg(psmouse, 0x0163) == -1)
    1548                 :            :                 goto error;
    1549         [ #  # ]:          0 :         if (alps_command_mode_write_reg(psmouse, 0x0163, 0x03))
    1550                 :            :                 goto error;
    1551                 :            : 
    1552         [ #  # ]:          0 :         if (alps_command_mode_read_reg(psmouse, 0x0162) == -1)
    1553                 :            :                 goto error;
    1554         [ #  # ]:          0 :         if (alps_command_mode_write_reg(psmouse, 0x0162, 0x04))
    1555                 :            :                 goto error;
    1556                 :            : 
    1557                 :            :         alps_exit_command_mode(psmouse);
    1558                 :            : 
    1559                 :            :         /* Set rate and enable data reporting */
    1560                 :          0 :         param[0] = 0x64;
    1561   [ #  #  #  # ]:          0 :         if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE) ||
    1562                 :          0 :             ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE)) {
    1563                 :          0 :                 psmouse_err(psmouse, "Failed to enable data reporting\n");
    1564                 :          0 :                 return -1;
    1565                 :            :         }
    1566                 :            : 
    1567                 :            :         return 0;
    1568                 :            : 
    1569                 :            : error:
    1570                 :            :         /*
    1571                 :            :          * Leaving the touchpad in command mode will essentially render
    1572                 :            :          * it unusable until the machine reboots, so exit it here just
    1573                 :            :          * to be safe
    1574                 :            :          */
    1575                 :            :         alps_exit_command_mode(psmouse);
    1576                 :            :         return -1;
    1577                 :            : }
    1578                 :            : 
    1579                 :          0 : static int alps_hw_init_rushmore_v3(struct psmouse *psmouse)
    1580                 :            : {
    1581                 :          0 :         struct alps_data *priv = psmouse->private;
    1582                 :          0 :         struct ps2dev *ps2dev = &psmouse->ps2dev;
    1583                 :            :         int reg_val, ret = -1;
    1584                 :            : 
    1585         [ #  # ]:          0 :         if (priv->flags & ALPS_DUALPOINT) {
    1586                 :          0 :                 reg_val = alps_setup_trackstick_v3(psmouse,
    1587                 :            :                                                    ALPS_REG_BASE_RUSHMORE);
    1588         [ #  # ]:          0 :                 if (reg_val == -EIO)
    1589                 :            :                         goto error;
    1590         [ #  # ]:          0 :                 if (reg_val == -ENODEV)
    1591                 :          0 :                         priv->flags &= ~ALPS_DUALPOINT;
    1592                 :            :         }
    1593                 :            : 
    1594   [ #  #  #  # ]:          0 :         if (alps_enter_command_mode(psmouse) ||
    1595         [ #  # ]:          0 :             alps_command_mode_read_reg(psmouse, 0xc2d9) == -1 ||
    1596                 :          0 :             alps_command_mode_write_reg(psmouse, 0xc2cb, 0x00))
    1597                 :            :                 goto error;
    1598                 :            : 
    1599                 :          0 :         reg_val = alps_command_mode_read_reg(psmouse, 0xc2c6);
    1600         [ #  # ]:          0 :         if (reg_val == -1)
    1601                 :            :                 goto error;
    1602         [ #  # ]:          0 :         if (__alps_command_mode_write_reg(psmouse, reg_val & 0xfd))
    1603                 :            :                 goto error;
    1604                 :            : 
    1605         [ #  # ]:          0 :         if (alps_command_mode_write_reg(psmouse, 0xc2c9, 0x64))
    1606                 :            :                 goto error;
    1607                 :            : 
    1608                 :            :         /* enter absolute mode */
    1609                 :          0 :         reg_val = alps_command_mode_read_reg(psmouse, 0xc2c4);
    1610         [ #  # ]:          0 :         if (reg_val == -1)
    1611                 :            :                 goto error;
    1612         [ #  # ]:          0 :         if (__alps_command_mode_write_reg(psmouse, reg_val | 0x02))
    1613                 :            :                 goto error;
    1614                 :            : 
    1615                 :            :         alps_exit_command_mode(psmouse);
    1616                 :          0 :         return ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE);
    1617                 :            : 
    1618                 :            : error:
    1619                 :            :         alps_exit_command_mode(psmouse);
    1620                 :            :         return ret;
    1621                 :            : }
    1622                 :            : 
    1623                 :            : /* Must be in command mode when calling this function */
    1624                 :          0 : static int alps_absolute_mode_v4(struct psmouse *psmouse)
    1625                 :            : {
    1626                 :            :         int reg_val;
    1627                 :            : 
    1628                 :          0 :         reg_val = alps_command_mode_read_reg(psmouse, 0x0004);
    1629         [ #  # ]:          0 :         if (reg_val == -1)
    1630                 :            :                 return -1;
    1631                 :            : 
    1632                 :          0 :         reg_val |= 0x02;
    1633         [ #  # ]:          0 :         if (__alps_command_mode_write_reg(psmouse, reg_val))
    1634                 :            :                 return -1;
    1635                 :            : 
    1636                 :          0 :         return 0;
    1637                 :            : }
    1638                 :            : 
    1639                 :          0 : static int alps_hw_init_v4(struct psmouse *psmouse)
    1640                 :            : {
    1641                 :          0 :         struct ps2dev *ps2dev = &psmouse->ps2dev;
    1642                 :            :         unsigned char param[4];
    1643                 :            : 
    1644         [ #  # ]:          0 :         if (alps_enter_command_mode(psmouse))
    1645                 :            :                 goto error;
    1646                 :            : 
    1647         [ #  # ]:          0 :         if (alps_absolute_mode_v4(psmouse)) {
    1648                 :          0 :                 psmouse_err(psmouse, "Failed to enter absolute mode\n");
    1649                 :          0 :                 goto error;
    1650                 :            :         }
    1651                 :            : 
    1652         [ #  # ]:          0 :         if (alps_command_mode_write_reg(psmouse, 0x0007, 0x8c))
    1653                 :            :                 goto error;
    1654                 :            : 
    1655         [ #  # ]:          0 :         if (alps_command_mode_write_reg(psmouse, 0x0149, 0x03))
    1656                 :            :                 goto error;
    1657                 :            : 
    1658         [ #  # ]:          0 :         if (alps_command_mode_write_reg(psmouse, 0x0160, 0x03))
    1659                 :            :                 goto error;
    1660                 :            : 
    1661         [ #  # ]:          0 :         if (alps_command_mode_write_reg(psmouse, 0x017f, 0x15))
    1662                 :            :                 goto error;
    1663                 :            : 
    1664         [ #  # ]:          0 :         if (alps_command_mode_write_reg(psmouse, 0x0151, 0x01))
    1665                 :            :                 goto error;
    1666                 :            : 
    1667         [ #  # ]:          0 :         if (alps_command_mode_write_reg(psmouse, 0x0168, 0x03))
    1668                 :            :                 goto error;
    1669                 :            : 
    1670         [ #  # ]:          0 :         if (alps_command_mode_write_reg(psmouse, 0x014a, 0x03))
    1671                 :            :                 goto error;
    1672                 :            : 
    1673         [ #  # ]:          0 :         if (alps_command_mode_write_reg(psmouse, 0x0161, 0x03))
    1674                 :            :                 goto error;
    1675                 :            : 
    1676                 :            :         alps_exit_command_mode(psmouse);
    1677                 :            : 
    1678                 :            :         /*
    1679                 :            :          * This sequence changes the output from a 9-byte to an
    1680                 :            :          * 8-byte format. All the same data seems to be present,
    1681                 :            :          * just in a more compact format.
    1682                 :            :          */
    1683                 :          0 :         param[0] = 0xc8;
    1684                 :          0 :         param[1] = 0x64;
    1685                 :          0 :         param[2] = 0x50;
    1686   [ #  #  #  # ]:          0 :         if (ps2_command(ps2dev, &param[0], PSMOUSE_CMD_SETRATE) ||
    1687         [ #  # ]:          0 :             ps2_command(ps2dev, &param[1], PSMOUSE_CMD_SETRATE) ||
    1688         [ #  # ]:          0 :             ps2_command(ps2dev, &param[2], PSMOUSE_CMD_SETRATE) ||
    1689                 :          0 :             ps2_command(ps2dev, param, PSMOUSE_CMD_GETID))
    1690                 :            :                 return -1;
    1691                 :            : 
    1692                 :            :         /* Set rate and enable data reporting */
    1693                 :          0 :         param[0] = 0x64;
    1694   [ #  #  #  # ]:          0 :         if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE) ||
    1695                 :          0 :             ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE)) {
    1696                 :          0 :                 psmouse_err(psmouse, "Failed to enable data reporting\n");
    1697                 :          0 :                 return -1;
    1698                 :            :         }
    1699                 :            : 
    1700                 :            :         return 0;
    1701                 :            : 
    1702                 :            : error:
    1703                 :            :         /*
    1704                 :            :          * Leaving the touchpad in command mode will essentially render
    1705                 :            :          * it unusable until the machine reboots, so exit it here just
    1706                 :            :          * to be safe
    1707                 :            :          */
    1708                 :            :         alps_exit_command_mode(psmouse);
    1709                 :            :         return -1;
    1710                 :            : }
    1711                 :            : 
    1712                 :          0 : static int alps_hw_init_dolphin_v1(struct psmouse *psmouse)
    1713                 :            : {
    1714                 :          0 :         struct ps2dev *ps2dev = &psmouse->ps2dev;
    1715                 :            :         unsigned char param[2];
    1716                 :            : 
    1717                 :            :         /* This is dolphin "v1" as empirically defined by florin9doi */
    1718                 :          0 :         param[0] = 0x64;
    1719                 :          0 :         param[1] = 0x28;
    1720                 :            : 
    1721   [ #  #  #  # ]:          0 :         if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSTREAM) ||
    1722         [ #  # ]:          0 :             ps2_command(ps2dev, &param[0], PSMOUSE_CMD_SETRATE) ||
    1723                 :          0 :             ps2_command(ps2dev, &param[1], PSMOUSE_CMD_SETRATE))
    1724                 :            :                 return -1;
    1725                 :            : 
    1726                 :            :         return 0;
    1727                 :            : }
    1728                 :            : 
    1729                 :          0 : static void alps_set_defaults(struct alps_data *priv)
    1730                 :            : {
    1731                 :          0 :         priv->byte0 = 0x8f;
    1732                 :          0 :         priv->mask0 = 0x8f;
    1733                 :          0 :         priv->flags = ALPS_DUALPOINT;
    1734                 :            : 
    1735                 :          0 :         priv->x_max = 2000;
    1736                 :          0 :         priv->y_max = 1400;
    1737                 :          0 :         priv->x_bits = 15;
    1738                 :          0 :         priv->y_bits = 11;
    1739                 :            : 
    1740   [ #  #  #  #  :          0 :         switch (priv->proto_version) {
                   #  # ]
    1741                 :            :         case ALPS_PROTO_V1:
    1742                 :            :         case ALPS_PROTO_V2:
    1743                 :          0 :                 priv->hw_init = alps_hw_init_v1_v2;
    1744                 :          0 :                 priv->process_packet = alps_process_packet_v1_v2;
    1745                 :          0 :                 priv->set_abs_params = alps_set_abs_params_st;
    1746                 :          0 :                 priv->x_max = 1023;
    1747                 :          0 :                 priv->y_max = 767;
    1748                 :          0 :                 break;
    1749                 :            :         case ALPS_PROTO_V3:
    1750                 :          0 :                 priv->hw_init = alps_hw_init_v3;
    1751                 :          0 :                 priv->process_packet = alps_process_packet_v3;
    1752                 :          0 :                 priv->set_abs_params = alps_set_abs_params_mt;
    1753                 :          0 :                 priv->decode_fields = alps_decode_pinnacle;
    1754                 :          0 :                 priv->nibble_commands = alps_v3_nibble_commands;
    1755                 :          0 :                 priv->addr_command = PSMOUSE_CMD_RESET_WRAP;
    1756                 :          0 :                 break;
    1757                 :            :         case ALPS_PROTO_V4:
    1758                 :          0 :                 priv->hw_init = alps_hw_init_v4;
    1759                 :          0 :                 priv->process_packet = alps_process_packet_v4;
    1760                 :          0 :                 priv->set_abs_params = alps_set_abs_params_mt;
    1761                 :          0 :                 priv->nibble_commands = alps_v4_nibble_commands;
    1762                 :          0 :                 priv->addr_command = PSMOUSE_CMD_DISABLE;
    1763                 :          0 :                 break;
    1764                 :            :         case ALPS_PROTO_V5:
    1765                 :          0 :                 priv->hw_init = alps_hw_init_dolphin_v1;
    1766                 :          0 :                 priv->process_packet = alps_process_packet_v3;
    1767                 :          0 :                 priv->decode_fields = alps_decode_dolphin;
    1768                 :          0 :                 priv->set_abs_params = alps_set_abs_params_mt;
    1769                 :          0 :                 priv->nibble_commands = alps_v3_nibble_commands;
    1770                 :          0 :                 priv->addr_command = PSMOUSE_CMD_RESET_WRAP;
    1771                 :          0 :                 priv->byte0 = 0xc8;
    1772                 :          0 :                 priv->mask0 = 0xc8;
    1773                 :          0 :                 priv->flags = 0;
    1774                 :          0 :                 priv->x_max = 1360;
    1775                 :          0 :                 priv->y_max = 660;
    1776                 :          0 :                 priv->x_bits = 23;
    1777                 :          0 :                 priv->y_bits = 12;
    1778                 :          0 :                 break;
    1779                 :            :         case ALPS_PROTO_V6:
    1780                 :          0 :                 priv->hw_init = alps_hw_init_v6;
    1781                 :          0 :                 priv->process_packet = alps_process_packet_v6;
    1782                 :          0 :                 priv->set_abs_params = alps_set_abs_params_st;
    1783                 :          0 :                 priv->nibble_commands = alps_v6_nibble_commands;
    1784                 :          0 :                 priv->x_max = 2047;
    1785                 :          0 :                 priv->y_max = 1535;
    1786                 :          0 :                 break;
    1787                 :            :         }
    1788                 :          0 : }
    1789                 :            : 
    1790                 :          0 : static int alps_match_table(struct psmouse *psmouse, struct alps_data *priv,
    1791                 :            :                             unsigned char *e7, unsigned char *ec)
    1792                 :            : {
    1793                 :            :         const struct alps_model_info *model;
    1794                 :            :         int i;
    1795                 :            : 
    1796         [ #  # ]:          0 :         for (i = 0; i < ARRAY_SIZE(alps_model_data); i++) {
    1797                 :          0 :                 model = &alps_model_data[i];
    1798                 :            : 
    1799 [ #  # ][ #  # ]:          0 :                 if (!memcmp(e7, model->signature, sizeof(model->signature)) &&
    1800         [ #  # ]:          0 :                     (!model->command_mode_resp ||
    1801                 :          0 :                      model->command_mode_resp == ec[2])) {
    1802                 :            : 
    1803                 :          0 :                         priv->proto_version = model->proto_version;
    1804                 :          0 :                         alps_set_defaults(priv);
    1805                 :            : 
    1806                 :          0 :                         priv->flags = model->flags;
    1807                 :          0 :                         priv->byte0 = model->byte0;
    1808                 :          0 :                         priv->mask0 = model->mask0;
    1809                 :            : 
    1810                 :            :                         return 0;
    1811                 :            :                 }
    1812                 :            :         }
    1813                 :            : 
    1814                 :            :         return -EINVAL;
    1815                 :            : }
    1816                 :            : 
    1817                 :          0 : static int alps_identify(struct psmouse *psmouse, struct alps_data *priv)
    1818                 :            : {
    1819                 :            :         unsigned char e6[4], e7[4], ec[4];
    1820                 :            : 
    1821                 :            :         /*
    1822                 :            :          * First try "E6 report".
    1823                 :            :          * ALPS should return 0,0,10 or 0,0,100 if no buttons are pressed.
    1824                 :            :          * The bits 0-2 of the first byte will be 1s if some buttons are
    1825                 :            :          * pressed.
    1826                 :            :          */
    1827         [ #  # ]:          0 :         if (alps_rpt_cmd(psmouse, PSMOUSE_CMD_SETRES,
    1828                 :            :                          PSMOUSE_CMD_SETSCALE11, e6))
    1829                 :            :                 return -EIO;
    1830                 :            : 
    1831 [ #  # ][ #  # ]:          0 :         if ((e6[0] & 0xf8) != 0 || e6[1] != 0 || (e6[2] != 10 && e6[2] != 100))
                 [ #  # ]
    1832                 :            :                 return -EINVAL;
    1833                 :            : 
    1834                 :            :         /*
    1835                 :            :          * Now get the "E7" and "EC" reports.  These will uniquely identify
    1836                 :            :          * most ALPS touchpads.
    1837                 :            :          */
    1838         [ #  # ]:          0 :         if (alps_rpt_cmd(psmouse, PSMOUSE_CMD_SETRES,
    1839         [ #  # ]:          0 :                          PSMOUSE_CMD_SETSCALE21, e7) ||
    1840                 :          0 :             alps_rpt_cmd(psmouse, PSMOUSE_CMD_SETRES,
    1841         [ #  # ]:          0 :                          PSMOUSE_CMD_RESET_WRAP, ec) ||
    1842                 :            :             alps_exit_command_mode(psmouse))
    1843                 :            :                 return -EIO;
    1844                 :            : 
    1845         [ #  # ]:          0 :         if (alps_match_table(psmouse, priv, e7, ec) == 0) {
    1846                 :            :                 return 0;
    1847 [ #  # ][ #  # ]:          0 :         } else if (e7[0] == 0x73 && e7[1] == 0x03 && e7[2] == 0x50 &&
         [ #  # ][ #  # ]
    1848         [ #  # ]:          0 :                    ec[0] == 0x73 && ec[1] == 0x01) {
    1849                 :          0 :                 priv->proto_version = ALPS_PROTO_V5;
    1850                 :          0 :                 alps_set_defaults(priv);
    1851                 :            : 
    1852                 :          0 :                 return 0;
    1853 [ #  # ][ #  # ]:          0 :         } else if (ec[0] == 0x88 && ec[1] == 0x08) {
    1854                 :          0 :                 priv->proto_version = ALPS_PROTO_V3;
    1855                 :          0 :                 alps_set_defaults(priv);
    1856                 :            : 
    1857                 :          0 :                 priv->hw_init = alps_hw_init_rushmore_v3;
    1858                 :          0 :                 priv->decode_fields = alps_decode_rushmore;
    1859                 :          0 :                 priv->x_bits = 16;
    1860                 :          0 :                 priv->y_bits = 12;
    1861                 :            : 
    1862                 :            :                 /* hack to make addr_command, nibble_command available */
    1863                 :          0 :                 psmouse->private = priv;
    1864                 :            : 
    1865         [ #  # ]:          0 :                 if (alps_probe_trackstick_v3(psmouse, ALPS_REG_BASE_RUSHMORE))
    1866                 :          0 :                         priv->flags &= ~ALPS_DUALPOINT;
    1867                 :            : 
    1868                 :            :                 return 0;
    1869 [ #  # ][ #  # ]:          0 :         } else if (ec[0] == 0x88 && ec[1] == 0x07 &&
                 [ #  # ]
    1870         [ #  # ]:          0 :                    ec[2] >= 0x90 && ec[2] <= 0x9d) {
    1871                 :          0 :                 priv->proto_version = ALPS_PROTO_V3;
    1872                 :          0 :                 alps_set_defaults(priv);
    1873                 :            : 
    1874                 :          0 :                 return 0;
    1875                 :            :         }
    1876                 :            : 
    1877                 :          0 :         psmouse_info(psmouse,
    1878                 :            :                      "Unknown ALPS touchpad: E7=%3ph, EC=%3ph\n", e7, ec);
    1879                 :            : 
    1880                 :          0 :         return -EINVAL;
    1881                 :            : }
    1882                 :            : 
    1883                 :          0 : static int alps_reconnect(struct psmouse *psmouse)
    1884                 :            : {
    1885                 :          0 :         struct alps_data *priv = psmouse->private;
    1886                 :            : 
    1887                 :          0 :         psmouse_reset(psmouse);
    1888                 :            : 
    1889         [ #  # ]:          0 :         if (alps_identify(psmouse, priv) < 0)
    1890                 :            :                 return -1;
    1891                 :            : 
    1892                 :          0 :         return priv->hw_init(psmouse);
    1893                 :            : }
    1894                 :            : 
    1895                 :          0 : static void alps_disconnect(struct psmouse *psmouse)
    1896                 :            : {
    1897                 :          0 :         struct alps_data *priv = psmouse->private;
    1898                 :            : 
    1899                 :          0 :         psmouse_reset(psmouse);
    1900                 :          0 :         del_timer_sync(&priv->timer);
    1901                 :          0 :         input_unregister_device(priv->dev2);
    1902                 :          0 :         kfree(priv);
    1903                 :          0 : }
    1904                 :            : 
    1905                 :          0 : static void alps_set_abs_params_st(struct alps_data *priv,
    1906                 :            :                                    struct input_dev *dev1)
    1907                 :            : {
    1908                 :          0 :         input_set_abs_params(dev1, ABS_X, 0, priv->x_max, 0, 0);
    1909                 :          0 :         input_set_abs_params(dev1, ABS_Y, 0, priv->y_max, 0, 0);
    1910                 :          0 : }
    1911                 :            : 
    1912                 :          0 : static void alps_set_abs_params_mt(struct alps_data *priv,
    1913                 :            :                                    struct input_dev *dev1)
    1914                 :            : {
    1915                 :          0 :         set_bit(INPUT_PROP_SEMI_MT, dev1->propbit);
    1916                 :          0 :         input_mt_init_slots(dev1, 2, 0);
    1917                 :          0 :         input_set_abs_params(dev1, ABS_MT_POSITION_X, 0, priv->x_max, 0, 0);
    1918                 :          0 :         input_set_abs_params(dev1, ABS_MT_POSITION_Y, 0, priv->y_max, 0, 0);
    1919                 :            : 
    1920                 :          0 :         set_bit(BTN_TOOL_DOUBLETAP, dev1->keybit);
    1921                 :          0 :         set_bit(BTN_TOOL_TRIPLETAP, dev1->keybit);
    1922                 :          0 :         set_bit(BTN_TOOL_QUADTAP, dev1->keybit);
    1923                 :            : 
    1924                 :          0 :         input_set_abs_params(dev1, ABS_X, 0, priv->x_max, 0, 0);
    1925                 :          0 :         input_set_abs_params(dev1, ABS_Y, 0, priv->y_max, 0, 0);
    1926                 :          0 : }
    1927                 :            : 
    1928                 :          0 : int alps_init(struct psmouse *psmouse)
    1929                 :            : {
    1930                 :            :         struct alps_data *priv;
    1931                 :          0 :         struct input_dev *dev1 = psmouse->dev, *dev2;
    1932                 :            : 
    1933                 :            :         priv = kzalloc(sizeof(struct alps_data), GFP_KERNEL);
    1934                 :          0 :         dev2 = input_allocate_device();
    1935         [ #  # ]:          0 :         if (!priv || !dev2)
    1936                 :            :                 goto init_fail;
    1937                 :            : 
    1938                 :          0 :         priv->dev2 = dev2;
    1939                 :          0 :         setup_timer(&priv->timer, alps_flush_packet, (unsigned long)psmouse);
    1940                 :            : 
    1941                 :          0 :         psmouse->private = priv;
    1942                 :            : 
    1943                 :          0 :         psmouse_reset(psmouse);
    1944                 :            : 
    1945         [ #  # ]:          0 :         if (alps_identify(psmouse, priv) < 0)
    1946                 :            :                 goto init_fail;
    1947                 :            : 
    1948         [ #  # ]:          0 :         if (priv->hw_init(psmouse))
    1949                 :            :                 goto init_fail;
    1950                 :            : 
    1951                 :            :         /*
    1952                 :            :          * Undo part of setup done for us by psmouse core since touchpad
    1953                 :            :          * is not a relative device.
    1954                 :            :          */
    1955                 :            :         __clear_bit(EV_REL, dev1->evbit);
    1956                 :            :         __clear_bit(REL_X, dev1->relbit);
    1957                 :            :         __clear_bit(REL_Y, dev1->relbit);
    1958                 :            : 
    1959                 :            :         /*
    1960                 :            :          * Now set up our capabilities.
    1961                 :            :          */
    1962                 :          0 :         dev1->evbit[BIT_WORD(EV_KEY)] |= BIT_MASK(EV_KEY);
    1963                 :          0 :         dev1->keybit[BIT_WORD(BTN_TOUCH)] |= BIT_MASK(BTN_TOUCH);
    1964                 :          0 :         dev1->keybit[BIT_WORD(BTN_TOOL_FINGER)] |= BIT_MASK(BTN_TOOL_FINGER);
    1965                 :          0 :         dev1->keybit[BIT_WORD(BTN_LEFT)] |=
    1966                 :            :                 BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT);
    1967                 :            : 
    1968                 :          0 :         dev1->evbit[BIT_WORD(EV_ABS)] |= BIT_MASK(EV_ABS);
    1969                 :            : 
    1970                 :          0 :         priv->set_abs_params(priv, dev1);
    1971                 :          0 :         input_set_abs_params(dev1, ABS_PRESSURE, 0, 127, 0, 0);
    1972                 :            : 
    1973         [ #  # ]:          0 :         if (priv->flags & ALPS_WHEEL) {
    1974                 :          0 :                 dev1->evbit[BIT_WORD(EV_REL)] |= BIT_MASK(EV_REL);
    1975                 :          0 :                 dev1->relbit[BIT_WORD(REL_WHEEL)] |= BIT_MASK(REL_WHEEL);
    1976                 :            :         }
    1977                 :            : 
    1978         [ #  # ]:          0 :         if (priv->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) {
    1979                 :          0 :                 dev1->keybit[BIT_WORD(BTN_FORWARD)] |= BIT_MASK(BTN_FORWARD);
    1980                 :          0 :                 dev1->keybit[BIT_WORD(BTN_BACK)] |= BIT_MASK(BTN_BACK);
    1981                 :            :         }
    1982                 :            : 
    1983         [ #  # ]:          0 :         if (priv->flags & ALPS_FOUR_BUTTONS) {
    1984                 :          0 :                 dev1->keybit[BIT_WORD(BTN_0)] |= BIT_MASK(BTN_0);
    1985                 :          0 :                 dev1->keybit[BIT_WORD(BTN_1)] |= BIT_MASK(BTN_1);
    1986                 :          0 :                 dev1->keybit[BIT_WORD(BTN_2)] |= BIT_MASK(BTN_2);
    1987                 :          0 :                 dev1->keybit[BIT_WORD(BTN_3)] |= BIT_MASK(BTN_3);
    1988                 :            :         } else {
    1989                 :          0 :                 dev1->keybit[BIT_WORD(BTN_MIDDLE)] |= BIT_MASK(BTN_MIDDLE);
    1990                 :            :         }
    1991                 :            : 
    1992                 :          0 :         snprintf(priv->phys, sizeof(priv->phys), "%s/input1", psmouse->ps2dev.serio->phys);
    1993                 :          0 :         dev2->phys = priv->phys;
    1994                 :          0 :         dev2->name = (priv->flags & ALPS_DUALPOINT) ?
    1995         [ #  # ]:          0 :                      "DualPoint Stick" : "ALPS PS/2 Device";
    1996                 :          0 :         dev2->id.bustype = BUS_I8042;
    1997                 :          0 :         dev2->id.vendor  = 0x0002;
    1998                 :          0 :         dev2->id.product = PSMOUSE_ALPS;
    1999                 :          0 :         dev2->id.version = 0x0000;
    2000                 :          0 :         dev2->dev.parent = &psmouse->ps2dev.serio->dev;
    2001                 :            : 
    2002                 :          0 :         dev2->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
    2003                 :          0 :         dev2->relbit[BIT_WORD(REL_X)] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
    2004                 :          0 :         dev2->keybit[BIT_WORD(BTN_LEFT)] =
    2005                 :            :                 BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
    2006                 :            : 
    2007         [ #  # ]:          0 :         if (input_register_device(priv->dev2))
    2008                 :            :                 goto init_fail;
    2009                 :            : 
    2010                 :          0 :         psmouse->protocol_handler = alps_process_byte;
    2011                 :          0 :         psmouse->poll = alps_poll;
    2012                 :          0 :         psmouse->disconnect = alps_disconnect;
    2013                 :          0 :         psmouse->reconnect = alps_reconnect;
    2014         [ #  # ]:          0 :         psmouse->pktsize = priv->proto_version == ALPS_PROTO_V4 ? 8 : 6;
    2015                 :            : 
    2016                 :            :         /* We are having trouble resyncing ALPS touchpads so disable it for now */
    2017                 :          0 :         psmouse->resync_time = 0;
    2018                 :            : 
    2019                 :          0 :         return 0;
    2020                 :            : 
    2021                 :            : init_fail:
    2022                 :          0 :         psmouse_reset(psmouse);
    2023                 :          0 :         input_free_device(dev2);
    2024                 :          0 :         kfree(priv);
    2025                 :          0 :         psmouse->private = NULL;
    2026                 :          0 :         return -1;
    2027                 :            : }
    2028                 :            : 
    2029                 :          0 : int alps_detect(struct psmouse *psmouse, bool set_properties)
    2030                 :            : {
    2031                 :            :         struct alps_data dummy;
    2032                 :            : 
    2033         [ #  # ]:          0 :         if (alps_identify(psmouse, &dummy) < 0)
    2034                 :            :                 return -1;
    2035                 :            : 
    2036         [ #  # ]:          0 :         if (set_properties) {
    2037                 :          0 :                 psmouse->vendor = "ALPS";
    2038                 :          0 :                 psmouse->name = dummy.flags & ALPS_DUALPOINT ?
    2039         [ #  # ]:          0 :                                 "DualPoint TouchPad" : "GlidePoint";
    2040                 :          0 :                 psmouse->model = dummy.proto_version << 8;
    2041                 :            :         }
    2042                 :            :         return 0;
    2043                 :            : }
    2044                 :            : 

Generated by: LCOV version 1.9