1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * ALPS touchpad PS/2 mouse driver 4*4882a593Smuzhiyun * 5*4882a593Smuzhiyun * Copyright (c) 2003 Peter Osterlund <petero2@telia.com> 6*4882a593Smuzhiyun * Copyright (c) 2005 Vojtech Pavlik <vojtech@suse.cz> 7*4882a593Smuzhiyun */ 8*4882a593Smuzhiyun 9*4882a593Smuzhiyun #ifndef _ALPS_H 10*4882a593Smuzhiyun #define _ALPS_H 11*4882a593Smuzhiyun 12*4882a593Smuzhiyun #include <linux/input/mt.h> 13*4882a593Smuzhiyun 14*4882a593Smuzhiyun #define ALPS_PROTO_V1 0x100 15*4882a593Smuzhiyun #define ALPS_PROTO_V2 0x200 16*4882a593Smuzhiyun #define ALPS_PROTO_V3 0x300 17*4882a593Smuzhiyun #define ALPS_PROTO_V3_RUSHMORE 0x310 18*4882a593Smuzhiyun #define ALPS_PROTO_V4 0x400 19*4882a593Smuzhiyun #define ALPS_PROTO_V5 0x500 20*4882a593Smuzhiyun #define ALPS_PROTO_V6 0x600 21*4882a593Smuzhiyun #define ALPS_PROTO_V7 0x700 /* t3btl t4s */ 22*4882a593Smuzhiyun #define ALPS_PROTO_V8 0x800 /* SS4btl SS4s */ 23*4882a593Smuzhiyun #define ALPS_PROTO_V9 0x900 /* ss3btl */ 24*4882a593Smuzhiyun 25*4882a593Smuzhiyun #define MAX_TOUCHES 4 26*4882a593Smuzhiyun 27*4882a593Smuzhiyun #define DOLPHIN_COUNT_PER_ELECTRODE 64 28*4882a593Smuzhiyun #define DOLPHIN_PROFILE_XOFFSET 8 /* x-electrode offset */ 29*4882a593Smuzhiyun #define DOLPHIN_PROFILE_YOFFSET 1 /* y-electrode offset */ 30*4882a593Smuzhiyun 31*4882a593Smuzhiyun /* 32*4882a593Smuzhiyun * enum SS4_PACKET_ID - defines the packet type for V8 33*4882a593Smuzhiyun * SS4_PACKET_ID_IDLE: There's no finger and no button activity. 34*4882a593Smuzhiyun * SS4_PACKET_ID_ONE: There's one finger on touchpad 35*4882a593Smuzhiyun * or there's button activities. 36*4882a593Smuzhiyun * SS4_PACKET_ID_TWO: There's two or more fingers on touchpad 37*4882a593Smuzhiyun * SS4_PACKET_ID_MULTI: There's three or more fingers on touchpad 38*4882a593Smuzhiyun * SS4_PACKET_ID_STICK: A stick pointer packet 39*4882a593Smuzhiyun */ 40*4882a593Smuzhiyun enum SS4_PACKET_ID { 41*4882a593Smuzhiyun SS4_PACKET_ID_IDLE = 0, 42*4882a593Smuzhiyun SS4_PACKET_ID_ONE, 43*4882a593Smuzhiyun SS4_PACKET_ID_TWO, 44*4882a593Smuzhiyun SS4_PACKET_ID_MULTI, 45*4882a593Smuzhiyun SS4_PACKET_ID_STICK, 46*4882a593Smuzhiyun }; 47*4882a593Smuzhiyun 48*4882a593Smuzhiyun #define SS4_COUNT_PER_ELECTRODE 256 49*4882a593Smuzhiyun #define SS4_NUMSENSOR_XOFFSET 7 50*4882a593Smuzhiyun #define SS4_NUMSENSOR_YOFFSET 7 51*4882a593Smuzhiyun #define SS4_MIN_PITCH_MM 50 52*4882a593Smuzhiyun 53*4882a593Smuzhiyun #define SS4_MASK_NORMAL_BUTTONS 0x07 54*4882a593Smuzhiyun 55*4882a593Smuzhiyun #define SS4PLUS_COUNT_PER_ELECTRODE 128 56*4882a593Smuzhiyun #define SS4PLUS_NUMSENSOR_XOFFSET 16 57*4882a593Smuzhiyun #define SS4PLUS_NUMSENSOR_YOFFSET 5 58*4882a593Smuzhiyun #define SS4PLUS_MIN_PITCH_MM 37 59*4882a593Smuzhiyun 60*4882a593Smuzhiyun #define IS_SS4PLUS_DEV(_b) (((_b[0]) == 0x73) && \ 61*4882a593Smuzhiyun ((_b[1]) == 0x03) && \ 62*4882a593Smuzhiyun ((_b[2]) == 0x28) \ 63*4882a593Smuzhiyun ) 64*4882a593Smuzhiyun 65*4882a593Smuzhiyun #define SS4_IS_IDLE_V2(_b) (((_b[0]) == 0x18) && \ 66*4882a593Smuzhiyun ((_b[1]) == 0x10) && \ 67*4882a593Smuzhiyun ((_b[2]) == 0x00) && \ 68*4882a593Smuzhiyun ((_b[3] & 0x88) == 0x08) && \ 69*4882a593Smuzhiyun ((_b[4]) == 0x10) && \ 70*4882a593Smuzhiyun ((_b[5]) == 0x00) \ 71*4882a593Smuzhiyun ) 72*4882a593Smuzhiyun 73*4882a593Smuzhiyun #define SS4_1F_X_V2(_b) (((_b[0]) & 0x0007) | \ 74*4882a593Smuzhiyun ((_b[1] << 3) & 0x0078) | \ 75*4882a593Smuzhiyun ((_b[1] << 2) & 0x0380) | \ 76*4882a593Smuzhiyun ((_b[2] << 5) & 0x1C00) \ 77*4882a593Smuzhiyun ) 78*4882a593Smuzhiyun 79*4882a593Smuzhiyun #define SS4_1F_Y_V2(_b) (((_b[2]) & 0x000F) | \ 80*4882a593Smuzhiyun ((_b[3] >> 2) & 0x0030) | \ 81*4882a593Smuzhiyun ((_b[4] << 6) & 0x03C0) | \ 82*4882a593Smuzhiyun ((_b[4] << 5) & 0x0C00) \ 83*4882a593Smuzhiyun ) 84*4882a593Smuzhiyun 85*4882a593Smuzhiyun #define SS4_1F_Z_V2(_b) (((_b[5]) & 0x0F) | \ 86*4882a593Smuzhiyun ((_b[5] >> 1) & 0x70) | \ 87*4882a593Smuzhiyun ((_b[4]) & 0x80) \ 88*4882a593Smuzhiyun ) 89*4882a593Smuzhiyun 90*4882a593Smuzhiyun #define SS4_1F_LFB_V2(_b) (((_b[2] >> 4) & 0x01) == 0x01) 91*4882a593Smuzhiyun 92*4882a593Smuzhiyun #define SS4_MF_LF_V2(_b, _i) ((_b[1 + (_i) * 3] & 0x0004) == 0x0004) 93*4882a593Smuzhiyun 94*4882a593Smuzhiyun #define SS4_BTN_V2(_b) ((_b[0] >> 5) & SS4_MASK_NORMAL_BUTTONS) 95*4882a593Smuzhiyun 96*4882a593Smuzhiyun #define SS4_STD_MF_X_V2(_b, _i) (((_b[0 + (_i) * 3] << 5) & 0x00E0) | \ 97*4882a593Smuzhiyun ((_b[1 + _i * 3] << 5) & 0x1F00) \ 98*4882a593Smuzhiyun ) 99*4882a593Smuzhiyun 100*4882a593Smuzhiyun #define SS4_PLUS_STD_MF_X_V2(_b, _i) (((_b[0 + (_i) * 3] << 4) & 0x0070) | \ 101*4882a593Smuzhiyun ((_b[1 + (_i) * 3] << 4) & 0x0F80) \ 102*4882a593Smuzhiyun ) 103*4882a593Smuzhiyun 104*4882a593Smuzhiyun #define SS4_STD_MF_Y_V2(_b, _i) (((_b[1 + (_i) * 3] << 3) & 0x0010) | \ 105*4882a593Smuzhiyun ((_b[2 + (_i) * 3] << 5) & 0x01E0) | \ 106*4882a593Smuzhiyun ((_b[2 + (_i) * 3] << 4) & 0x0E00) \ 107*4882a593Smuzhiyun ) 108*4882a593Smuzhiyun 109*4882a593Smuzhiyun #define SS4_BTL_MF_X_V2(_b, _i) (SS4_STD_MF_X_V2(_b, _i) | \ 110*4882a593Smuzhiyun ((_b[0 + (_i) * 3] >> 3) & 0x0010) \ 111*4882a593Smuzhiyun ) 112*4882a593Smuzhiyun 113*4882a593Smuzhiyun #define SS4_PLUS_BTL_MF_X_V2(_b, _i) (SS4_PLUS_STD_MF_X_V2(_b, _i) | \ 114*4882a593Smuzhiyun ((_b[0 + (_i) * 3] >> 4) & 0x0008) \ 115*4882a593Smuzhiyun ) 116*4882a593Smuzhiyun 117*4882a593Smuzhiyun #define SS4_BTL_MF_Y_V2(_b, _i) (SS4_STD_MF_Y_V2(_b, _i) | \ 118*4882a593Smuzhiyun ((_b[0 + (_i) * 3] >> 3) & 0x0008) \ 119*4882a593Smuzhiyun ) 120*4882a593Smuzhiyun 121*4882a593Smuzhiyun #define SS4_MF_Z_V2(_b, _i) (((_b[1 + (_i) * 3]) & 0x0001) | \ 122*4882a593Smuzhiyun ((_b[1 + (_i) * 3] >> 1) & 0x0002) \ 123*4882a593Smuzhiyun ) 124*4882a593Smuzhiyun 125*4882a593Smuzhiyun #define SS4_IS_MF_CONTINUE(_b) ((_b[2] & 0x10) == 0x10) 126*4882a593Smuzhiyun #define SS4_IS_5F_DETECTED(_b) ((_b[2] & 0x10) == 0x10) 127*4882a593Smuzhiyun 128*4882a593Smuzhiyun #define SS4_TS_X_V2(_b) (s8)( \ 129*4882a593Smuzhiyun ((_b[0] & 0x01) << 7) | \ 130*4882a593Smuzhiyun (_b[1] & 0x7F) \ 131*4882a593Smuzhiyun ) 132*4882a593Smuzhiyun 133*4882a593Smuzhiyun #define SS4_TS_Y_V2(_b) -(s8)( \ 134*4882a593Smuzhiyun ((_b[3] & 0x01) << 7) | \ 135*4882a593Smuzhiyun (_b[2] & 0x7F) \ 136*4882a593Smuzhiyun ) 137*4882a593Smuzhiyun 138*4882a593Smuzhiyun #define SS4_TS_Z_V2(_b) (s8)(_b[4] & 0x7F) 139*4882a593Smuzhiyun 140*4882a593Smuzhiyun 141*4882a593Smuzhiyun #define SS4_MFPACKET_NO_AX 8160 /* X-Coordinate value */ 142*4882a593Smuzhiyun #define SS4_MFPACKET_NO_AY 4080 /* Y-Coordinate value */ 143*4882a593Smuzhiyun #define SS4_MFPACKET_NO_AX_BL 8176 /* Buttonless X-Coord value */ 144*4882a593Smuzhiyun #define SS4_MFPACKET_NO_AY_BL 4088 /* Buttonless Y-Coord value */ 145*4882a593Smuzhiyun #define SS4_PLUS_MFPACKET_NO_AX 4080 /* SS4 PLUS, X */ 146*4882a593Smuzhiyun #define SS4_PLUS_MFPACKET_NO_AX_BL 4088 /* Buttonless SS4 PLUS, X */ 147*4882a593Smuzhiyun 148*4882a593Smuzhiyun /* 149*4882a593Smuzhiyun * enum V7_PACKET_ID - defines the packet type for V7 150*4882a593Smuzhiyun * V7_PACKET_ID_IDLE: There's no finger and no button activity. 151*4882a593Smuzhiyun * V7_PACKET_ID_TWO: There's one or two non-resting fingers on touchpad 152*4882a593Smuzhiyun * or there's button activities. 153*4882a593Smuzhiyun * V7_PACKET_ID_MULTI: There are at least three non-resting fingers. 154*4882a593Smuzhiyun * V7_PACKET_ID_NEW: The finger position in slot is not continues from 155*4882a593Smuzhiyun * previous packet. 156*4882a593Smuzhiyun */ 157*4882a593Smuzhiyun enum V7_PACKET_ID { 158*4882a593Smuzhiyun V7_PACKET_ID_IDLE, 159*4882a593Smuzhiyun V7_PACKET_ID_TWO, 160*4882a593Smuzhiyun V7_PACKET_ID_MULTI, 161*4882a593Smuzhiyun V7_PACKET_ID_NEW, 162*4882a593Smuzhiyun V7_PACKET_ID_UNKNOWN, 163*4882a593Smuzhiyun }; 164*4882a593Smuzhiyun 165*4882a593Smuzhiyun /** 166*4882a593Smuzhiyun * struct alps_protocol_info - information about protocol used by a device 167*4882a593Smuzhiyun * @version: Indicates V1/V2/V3/... 168*4882a593Smuzhiyun * @byte0: Helps figure out whether a position report packet matches the 169*4882a593Smuzhiyun * known format for this model. The first byte of the report, ANDed with 170*4882a593Smuzhiyun * mask0, should match byte0. 171*4882a593Smuzhiyun * @mask0: The mask used to check the first byte of the report. 172*4882a593Smuzhiyun * @flags: Additional device capabilities (passthrough port, trackstick, etc.). 173*4882a593Smuzhiyun */ 174*4882a593Smuzhiyun struct alps_protocol_info { 175*4882a593Smuzhiyun u16 version; 176*4882a593Smuzhiyun u8 byte0, mask0; 177*4882a593Smuzhiyun unsigned int flags; 178*4882a593Smuzhiyun }; 179*4882a593Smuzhiyun 180*4882a593Smuzhiyun /** 181*4882a593Smuzhiyun * struct alps_model_info - touchpad ID table 182*4882a593Smuzhiyun * @signature: E7 response string to match. 183*4882a593Smuzhiyun * @protocol_info: information about protocol used by the device. 184*4882a593Smuzhiyun * 185*4882a593Smuzhiyun * Many (but not all) ALPS touchpads can be identified by looking at the 186*4882a593Smuzhiyun * values returned in the "E7 report" and/or the "EC report." This table 187*4882a593Smuzhiyun * lists a number of such touchpads. 188*4882a593Smuzhiyun */ 189*4882a593Smuzhiyun struct alps_model_info { 190*4882a593Smuzhiyun u8 signature[3]; 191*4882a593Smuzhiyun struct alps_protocol_info protocol_info; 192*4882a593Smuzhiyun }; 193*4882a593Smuzhiyun 194*4882a593Smuzhiyun /** 195*4882a593Smuzhiyun * struct alps_nibble_commands - encodings for register accesses 196*4882a593Smuzhiyun * @command: PS/2 command used for the nibble 197*4882a593Smuzhiyun * @data: Data supplied as an argument to the PS/2 command, if applicable 198*4882a593Smuzhiyun * 199*4882a593Smuzhiyun * The ALPS protocol uses magic sequences to transmit binary data to the 200*4882a593Smuzhiyun * touchpad, as it is generally not OK to send arbitrary bytes out the 201*4882a593Smuzhiyun * PS/2 port. Each of the sequences in this table sends one nibble of the 202*4882a593Smuzhiyun * register address or (write) data. Different versions of the ALPS protocol 203*4882a593Smuzhiyun * use slightly different encodings. 204*4882a593Smuzhiyun */ 205*4882a593Smuzhiyun struct alps_nibble_commands { 206*4882a593Smuzhiyun int command; 207*4882a593Smuzhiyun unsigned char data; 208*4882a593Smuzhiyun }; 209*4882a593Smuzhiyun 210*4882a593Smuzhiyun struct alps_bitmap_point { 211*4882a593Smuzhiyun int start_bit; 212*4882a593Smuzhiyun int num_bits; 213*4882a593Smuzhiyun }; 214*4882a593Smuzhiyun 215*4882a593Smuzhiyun /** 216*4882a593Smuzhiyun * struct alps_fields - decoded version of the report packet 217*4882a593Smuzhiyun * @x_map: Bitmap of active X positions for MT. 218*4882a593Smuzhiyun * @y_map: Bitmap of active Y positions for MT. 219*4882a593Smuzhiyun * @fingers: Number of fingers for MT. 220*4882a593Smuzhiyun * @pressure: Pressure. 221*4882a593Smuzhiyun * @st: position for ST. 222*4882a593Smuzhiyun * @mt: position for MT. 223*4882a593Smuzhiyun * @first_mp: Packet is the first of a multi-packet report. 224*4882a593Smuzhiyun * @is_mp: Packet is part of a multi-packet report. 225*4882a593Smuzhiyun * @left: Left touchpad button is active. 226*4882a593Smuzhiyun * @right: Right touchpad button is active. 227*4882a593Smuzhiyun * @middle: Middle touchpad button is active. 228*4882a593Smuzhiyun * @ts_left: Left trackstick button is active. 229*4882a593Smuzhiyun * @ts_right: Right trackstick button is active. 230*4882a593Smuzhiyun * @ts_middle: Middle trackstick button is active. 231*4882a593Smuzhiyun */ 232*4882a593Smuzhiyun struct alps_fields { 233*4882a593Smuzhiyun unsigned int x_map; 234*4882a593Smuzhiyun unsigned int y_map; 235*4882a593Smuzhiyun unsigned int fingers; 236*4882a593Smuzhiyun 237*4882a593Smuzhiyun int pressure; 238*4882a593Smuzhiyun struct input_mt_pos st; 239*4882a593Smuzhiyun struct input_mt_pos mt[MAX_TOUCHES]; 240*4882a593Smuzhiyun 241*4882a593Smuzhiyun unsigned int first_mp:1; 242*4882a593Smuzhiyun unsigned int is_mp:1; 243*4882a593Smuzhiyun 244*4882a593Smuzhiyun unsigned int left:1; 245*4882a593Smuzhiyun unsigned int right:1; 246*4882a593Smuzhiyun unsigned int middle:1; 247*4882a593Smuzhiyun 248*4882a593Smuzhiyun unsigned int ts_left:1; 249*4882a593Smuzhiyun unsigned int ts_right:1; 250*4882a593Smuzhiyun unsigned int ts_middle:1; 251*4882a593Smuzhiyun }; 252*4882a593Smuzhiyun 253*4882a593Smuzhiyun /** 254*4882a593Smuzhiyun * struct alps_data - private data structure for the ALPS driver 255*4882a593Smuzhiyun * @psmouse: Pointer to parent psmouse device 256*4882a593Smuzhiyun * @dev2: Trackstick device (can be NULL). 257*4882a593Smuzhiyun * @dev3: Generic PS/2 mouse (can be NULL, delayed registering). 258*4882a593Smuzhiyun * @phys2: Physical path for the trackstick device. 259*4882a593Smuzhiyun * @phys3: Physical path for the generic PS/2 mouse. 260*4882a593Smuzhiyun * @dev3_register_work: Delayed work for registering PS/2 mouse. 261*4882a593Smuzhiyun * @nibble_commands: Command mapping used for touchpad register accesses. 262*4882a593Smuzhiyun * @addr_command: Command used to tell the touchpad that a register address 263*4882a593Smuzhiyun * follows. 264*4882a593Smuzhiyun * @proto_version: Indicates V1/V2/V3/... 265*4882a593Smuzhiyun * @byte0: Helps figure out whether a position report packet matches the 266*4882a593Smuzhiyun * known format for this model. The first byte of the report, ANDed with 267*4882a593Smuzhiyun * mask0, should match byte0. 268*4882a593Smuzhiyun * @mask0: The mask used to check the first byte of the report. 269*4882a593Smuzhiyun * @fw_ver: cached copy of firmware version (EC report) 270*4882a593Smuzhiyun * @flags: Additional device capabilities (passthrough port, trackstick, etc.). 271*4882a593Smuzhiyun * @x_max: Largest possible X position value. 272*4882a593Smuzhiyun * @y_max: Largest possible Y position value. 273*4882a593Smuzhiyun * @x_bits: Number of X bits in the MT bitmap. 274*4882a593Smuzhiyun * @y_bits: Number of Y bits in the MT bitmap. 275*4882a593Smuzhiyun * @hw_init: Protocol-specific hardware init function. 276*4882a593Smuzhiyun * @process_packet: Protocol-specific function to process a report packet. 277*4882a593Smuzhiyun * @decode_fields: Protocol-specific function to read packet bitfields. 278*4882a593Smuzhiyun * @set_abs_params: Protocol-specific function to configure the input_dev. 279*4882a593Smuzhiyun * @prev_fin: Finger bit from previous packet. 280*4882a593Smuzhiyun * @multi_packet: Multi-packet data in progress. 281*4882a593Smuzhiyun * @multi_data: Saved multi-packet data. 282*4882a593Smuzhiyun * @f: Decoded packet data fields. 283*4882a593Smuzhiyun * @quirks: Bitmap of ALPS_QUIRK_*. 284*4882a593Smuzhiyun * @timer: Timer for flushing out the final report packet in the stream. 285*4882a593Smuzhiyun */ 286*4882a593Smuzhiyun struct alps_data { 287*4882a593Smuzhiyun struct psmouse *psmouse; 288*4882a593Smuzhiyun struct input_dev *dev2; 289*4882a593Smuzhiyun struct input_dev *dev3; 290*4882a593Smuzhiyun char phys2[32]; 291*4882a593Smuzhiyun char phys3[32]; 292*4882a593Smuzhiyun struct delayed_work dev3_register_work; 293*4882a593Smuzhiyun 294*4882a593Smuzhiyun /* these are autodetected when the device is identified */ 295*4882a593Smuzhiyun const struct alps_nibble_commands *nibble_commands; 296*4882a593Smuzhiyun int addr_command; 297*4882a593Smuzhiyun u16 proto_version; 298*4882a593Smuzhiyun u8 byte0, mask0; 299*4882a593Smuzhiyun u8 dev_id[3]; 300*4882a593Smuzhiyun u8 fw_ver[3]; 301*4882a593Smuzhiyun int flags; 302*4882a593Smuzhiyun int x_max; 303*4882a593Smuzhiyun int y_max; 304*4882a593Smuzhiyun int x_bits; 305*4882a593Smuzhiyun int y_bits; 306*4882a593Smuzhiyun unsigned int x_res; 307*4882a593Smuzhiyun unsigned int y_res; 308*4882a593Smuzhiyun 309*4882a593Smuzhiyun int (*hw_init)(struct psmouse *psmouse); 310*4882a593Smuzhiyun void (*process_packet)(struct psmouse *psmouse); 311*4882a593Smuzhiyun int (*decode_fields)(struct alps_fields *f, unsigned char *p, 312*4882a593Smuzhiyun struct psmouse *psmouse); 313*4882a593Smuzhiyun void (*set_abs_params)(struct alps_data *priv, struct input_dev *dev1); 314*4882a593Smuzhiyun 315*4882a593Smuzhiyun int prev_fin; 316*4882a593Smuzhiyun int multi_packet; 317*4882a593Smuzhiyun int second_touch; 318*4882a593Smuzhiyun unsigned char multi_data[6]; 319*4882a593Smuzhiyun struct alps_fields f; 320*4882a593Smuzhiyun u8 quirks; 321*4882a593Smuzhiyun struct timer_list timer; 322*4882a593Smuzhiyun }; 323*4882a593Smuzhiyun 324*4882a593Smuzhiyun #define ALPS_QUIRK_TRACKSTICK_BUTTONS 1 /* trakcstick buttons in trackstick packet */ 325*4882a593Smuzhiyun 326*4882a593Smuzhiyun int alps_detect(struct psmouse *psmouse, bool set_properties); 327*4882a593Smuzhiyun int alps_init(struct psmouse *psmouse); 328*4882a593Smuzhiyun 329*4882a593Smuzhiyun #endif 330