1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * Elantech Touchpad driver (v6) 4*4882a593Smuzhiyun * 5*4882a593Smuzhiyun * Copyright (C) 2007-2009 Arjan Opmeer <arjan@opmeer.net> 6*4882a593Smuzhiyun * 7*4882a593Smuzhiyun * Trademarks are the property of their respective owners. 8*4882a593Smuzhiyun */ 9*4882a593Smuzhiyun 10*4882a593Smuzhiyun #ifndef _ELANTECH_H 11*4882a593Smuzhiyun #define _ELANTECH_H 12*4882a593Smuzhiyun 13*4882a593Smuzhiyun /* 14*4882a593Smuzhiyun * Command values for Synaptics style queries 15*4882a593Smuzhiyun */ 16*4882a593Smuzhiyun #define ETP_FW_ID_QUERY 0x00 17*4882a593Smuzhiyun #define ETP_FW_VERSION_QUERY 0x01 18*4882a593Smuzhiyun #define ETP_CAPABILITIES_QUERY 0x02 19*4882a593Smuzhiyun #define ETP_SAMPLE_QUERY 0x03 20*4882a593Smuzhiyun #define ETP_RESOLUTION_QUERY 0x04 21*4882a593Smuzhiyun #define ETP_ICBODY_QUERY 0x05 22*4882a593Smuzhiyun 23*4882a593Smuzhiyun /* 24*4882a593Smuzhiyun * Command values for register reading or writing 25*4882a593Smuzhiyun */ 26*4882a593Smuzhiyun #define ETP_REGISTER_READ 0x10 27*4882a593Smuzhiyun #define ETP_REGISTER_WRITE 0x11 28*4882a593Smuzhiyun #define ETP_REGISTER_READWRITE 0x00 29*4882a593Smuzhiyun 30*4882a593Smuzhiyun /* 31*4882a593Smuzhiyun * Hardware version 2 custom PS/2 command value 32*4882a593Smuzhiyun */ 33*4882a593Smuzhiyun #define ETP_PS2_CUSTOM_COMMAND 0xf8 34*4882a593Smuzhiyun 35*4882a593Smuzhiyun /* 36*4882a593Smuzhiyun * Times to retry a ps2_command and millisecond delay between tries 37*4882a593Smuzhiyun */ 38*4882a593Smuzhiyun #define ETP_PS2_COMMAND_TRIES 3 39*4882a593Smuzhiyun #define ETP_PS2_COMMAND_DELAY 500 40*4882a593Smuzhiyun 41*4882a593Smuzhiyun /* 42*4882a593Smuzhiyun * Times to try to read back a register and millisecond delay between tries 43*4882a593Smuzhiyun */ 44*4882a593Smuzhiyun #define ETP_READ_BACK_TRIES 5 45*4882a593Smuzhiyun #define ETP_READ_BACK_DELAY 2000 46*4882a593Smuzhiyun 47*4882a593Smuzhiyun /* 48*4882a593Smuzhiyun * Register bitmasks for hardware version 1 49*4882a593Smuzhiyun */ 50*4882a593Smuzhiyun #define ETP_R10_ABSOLUTE_MODE 0x04 51*4882a593Smuzhiyun #define ETP_R11_4_BYTE_MODE 0x02 52*4882a593Smuzhiyun 53*4882a593Smuzhiyun /* 54*4882a593Smuzhiyun * Capability bitmasks 55*4882a593Smuzhiyun */ 56*4882a593Smuzhiyun #define ETP_CAP_HAS_ROCKER 0x04 57*4882a593Smuzhiyun 58*4882a593Smuzhiyun /* 59*4882a593Smuzhiyun * One hard to find application note states that X axis range is 0 to 576 60*4882a593Smuzhiyun * and Y axis range is 0 to 384 for harware version 1. 61*4882a593Smuzhiyun * Edge fuzz might be necessary because of bezel around the touchpad 62*4882a593Smuzhiyun */ 63*4882a593Smuzhiyun #define ETP_EDGE_FUZZ_V1 32 64*4882a593Smuzhiyun 65*4882a593Smuzhiyun #define ETP_XMIN_V1 ( 0 + ETP_EDGE_FUZZ_V1) 66*4882a593Smuzhiyun #define ETP_XMAX_V1 (576 - ETP_EDGE_FUZZ_V1) 67*4882a593Smuzhiyun #define ETP_YMIN_V1 ( 0 + ETP_EDGE_FUZZ_V1) 68*4882a593Smuzhiyun #define ETP_YMAX_V1 (384 - ETP_EDGE_FUZZ_V1) 69*4882a593Smuzhiyun 70*4882a593Smuzhiyun /* 71*4882a593Smuzhiyun * The resolution for older v2 hardware doubled. 72*4882a593Smuzhiyun * (newer v2's firmware provides command so we can query) 73*4882a593Smuzhiyun */ 74*4882a593Smuzhiyun #define ETP_XMIN_V2 0 75*4882a593Smuzhiyun #define ETP_XMAX_V2 1152 76*4882a593Smuzhiyun #define ETP_YMIN_V2 0 77*4882a593Smuzhiyun #define ETP_YMAX_V2 768 78*4882a593Smuzhiyun 79*4882a593Smuzhiyun #define ETP_PMIN_V2 0 80*4882a593Smuzhiyun #define ETP_PMAX_V2 255 81*4882a593Smuzhiyun #define ETP_WMIN_V2 0 82*4882a593Smuzhiyun #define ETP_WMAX_V2 15 83*4882a593Smuzhiyun 84*4882a593Smuzhiyun /* 85*4882a593Smuzhiyun * v3 hardware has 2 kinds of packet types, 86*4882a593Smuzhiyun * v4 hardware has 3. 87*4882a593Smuzhiyun */ 88*4882a593Smuzhiyun #define PACKET_UNKNOWN 0x01 89*4882a593Smuzhiyun #define PACKET_DEBOUNCE 0x02 90*4882a593Smuzhiyun #define PACKET_V3_HEAD 0x03 91*4882a593Smuzhiyun #define PACKET_V3_TAIL 0x04 92*4882a593Smuzhiyun #define PACKET_V4_HEAD 0x05 93*4882a593Smuzhiyun #define PACKET_V4_MOTION 0x06 94*4882a593Smuzhiyun #define PACKET_V4_STATUS 0x07 95*4882a593Smuzhiyun #define PACKET_TRACKPOINT 0x08 96*4882a593Smuzhiyun 97*4882a593Smuzhiyun /* 98*4882a593Smuzhiyun * track up to 5 fingers for v4 hardware 99*4882a593Smuzhiyun */ 100*4882a593Smuzhiyun #define ETP_MAX_FINGERS 5 101*4882a593Smuzhiyun 102*4882a593Smuzhiyun /* 103*4882a593Smuzhiyun * weight value for v4 hardware 104*4882a593Smuzhiyun */ 105*4882a593Smuzhiyun #define ETP_WEIGHT_VALUE 5 106*4882a593Smuzhiyun 107*4882a593Smuzhiyun /* 108*4882a593Smuzhiyun * Bus information on 3rd byte of query ETP_RESOLUTION_QUERY(0x04) 109*4882a593Smuzhiyun */ 110*4882a593Smuzhiyun #define ETP_BUS_PS2_ONLY 0 111*4882a593Smuzhiyun #define ETP_BUS_SMB_ALERT_ONLY 1 112*4882a593Smuzhiyun #define ETP_BUS_SMB_HST_NTFY_ONLY 2 113*4882a593Smuzhiyun #define ETP_BUS_PS2_SMB_ALERT 3 114*4882a593Smuzhiyun #define ETP_BUS_PS2_SMB_HST_NTFY 4 115*4882a593Smuzhiyun 116*4882a593Smuzhiyun /* 117*4882a593Smuzhiyun * New ICs are either using SMBus Host Notify or just plain PS2. 118*4882a593Smuzhiyun * 119*4882a593Smuzhiyun * ETP_FW_VERSION_QUERY is: 120*4882a593Smuzhiyun * Byte 1: 121*4882a593Smuzhiyun * - bit 0..3: IC BODY 122*4882a593Smuzhiyun * Byte 2: 123*4882a593Smuzhiyun * - bit 4: HiddenButton 124*4882a593Smuzhiyun * - bit 5: PS2_SMBUS_NOTIFY 125*4882a593Smuzhiyun * - bit 6: PS2CRCCheck 126*4882a593Smuzhiyun */ 127*4882a593Smuzhiyun #define ETP_NEW_IC_SMBUS_HOST_NOTIFY(fw_version) \ 128*4882a593Smuzhiyun ((((fw_version) & 0x0f2000) == 0x0f2000) && \ 129*4882a593Smuzhiyun ((fw_version) & 0x0000ff) > 0) 130*4882a593Smuzhiyun 131*4882a593Smuzhiyun /* 132*4882a593Smuzhiyun * The base position for one finger, v4 hardware 133*4882a593Smuzhiyun */ 134*4882a593Smuzhiyun struct finger_pos { 135*4882a593Smuzhiyun unsigned int x; 136*4882a593Smuzhiyun unsigned int y; 137*4882a593Smuzhiyun }; 138*4882a593Smuzhiyun 139*4882a593Smuzhiyun struct elantech_device_info { 140*4882a593Smuzhiyun unsigned char capabilities[3]; 141*4882a593Smuzhiyun unsigned char samples[3]; 142*4882a593Smuzhiyun unsigned char debug; 143*4882a593Smuzhiyun unsigned char hw_version; 144*4882a593Smuzhiyun unsigned char pattern; 145*4882a593Smuzhiyun unsigned int fw_version; 146*4882a593Smuzhiyun unsigned int ic_version; 147*4882a593Smuzhiyun unsigned int product_id; 148*4882a593Smuzhiyun unsigned int x_min; 149*4882a593Smuzhiyun unsigned int y_min; 150*4882a593Smuzhiyun unsigned int x_max; 151*4882a593Smuzhiyun unsigned int y_max; 152*4882a593Smuzhiyun unsigned int x_res; 153*4882a593Smuzhiyun unsigned int y_res; 154*4882a593Smuzhiyun unsigned int x_traces; 155*4882a593Smuzhiyun unsigned int y_traces; 156*4882a593Smuzhiyun unsigned int width; 157*4882a593Smuzhiyun unsigned int bus; 158*4882a593Smuzhiyun bool paritycheck; 159*4882a593Smuzhiyun bool jumpy_cursor; 160*4882a593Smuzhiyun bool reports_pressure; 161*4882a593Smuzhiyun bool crc_enabled; 162*4882a593Smuzhiyun bool set_hw_resolution; 163*4882a593Smuzhiyun bool has_trackpoint; 164*4882a593Smuzhiyun bool has_middle_button; 165*4882a593Smuzhiyun int (*send_cmd)(struct psmouse *psmouse, unsigned char c, 166*4882a593Smuzhiyun unsigned char *param); 167*4882a593Smuzhiyun }; 168*4882a593Smuzhiyun 169*4882a593Smuzhiyun struct elantech_data { 170*4882a593Smuzhiyun struct input_dev *tp_dev; /* Relative device for trackpoint */ 171*4882a593Smuzhiyun char tp_phys[32]; 172*4882a593Smuzhiyun unsigned char reg_07; 173*4882a593Smuzhiyun unsigned char reg_10; 174*4882a593Smuzhiyun unsigned char reg_11; 175*4882a593Smuzhiyun unsigned char reg_20; 176*4882a593Smuzhiyun unsigned char reg_21; 177*4882a593Smuzhiyun unsigned char reg_22; 178*4882a593Smuzhiyun unsigned char reg_23; 179*4882a593Smuzhiyun unsigned char reg_24; 180*4882a593Smuzhiyun unsigned char reg_25; 181*4882a593Smuzhiyun unsigned char reg_26; 182*4882a593Smuzhiyun unsigned int single_finger_reports; 183*4882a593Smuzhiyun unsigned int y_max; 184*4882a593Smuzhiyun unsigned int width; 185*4882a593Smuzhiyun struct finger_pos mt[ETP_MAX_FINGERS]; 186*4882a593Smuzhiyun unsigned char parity[256]; 187*4882a593Smuzhiyun struct elantech_device_info info; 188*4882a593Smuzhiyun void (*original_set_rate)(struct psmouse *psmouse, unsigned int rate); 189*4882a593Smuzhiyun }; 190*4882a593Smuzhiyun 191*4882a593Smuzhiyun int elantech_detect(struct psmouse *psmouse, bool set_properties); 192*4882a593Smuzhiyun int elantech_init_ps2(struct psmouse *psmouse); 193*4882a593Smuzhiyun 194*4882a593Smuzhiyun #ifdef CONFIG_MOUSE_PS2_ELANTECH 195*4882a593Smuzhiyun int elantech_init(struct psmouse *psmouse); 196*4882a593Smuzhiyun #else elantech_init(struct psmouse * psmouse)197*4882a593Smuzhiyunstatic inline int elantech_init(struct psmouse *psmouse) 198*4882a593Smuzhiyun { 199*4882a593Smuzhiyun return -ENOSYS; 200*4882a593Smuzhiyun } 201*4882a593Smuzhiyun #endif /* CONFIG_MOUSE_PS2_ELANTECH */ 202*4882a593Smuzhiyun 203*4882a593Smuzhiyun int elantech_init_smbus(struct psmouse *psmouse); 204*4882a593Smuzhiyun 205*4882a593Smuzhiyun #endif 206