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

Generated by: LCOV version 1.9