Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  * ALPS touchpad PS/2 mouse driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  * Copyright (c) 2003 Neil Brown <neilb@cse.unsw.edu.au>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  * Copyright (c) 2003-2005 Peter Osterlund <petero2@telia.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  * Copyright (c) 2004 Dmitry Torokhov <dtor@mail.ru>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  * Copyright (c) 2005 Vojtech Pavlik <vojtech@suse.cz>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  * Copyright (c) 2009 Sebastian Kapfer <sebastian_kapfer@gmx.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11)  * ALPS detection, tap switching and status querying info is taken from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12)  * tpconfig utility (by C. Scott Ananian and Bruce Kall).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include <linux/input.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include <linux/input/mt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include <linux/serio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include <linux/libps2.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <linux/dmi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include "psmouse.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include "alps.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #include "trackpoint.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27)  * Definitions for ALPS version 3 and 4 command mode protocol
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #define ALPS_CMD_NIBBLE_10	0x01f2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #define ALPS_REG_BASE_RUSHMORE	0xc2c0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #define ALPS_REG_BASE_V7	0xc2c0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) #define ALPS_REG_BASE_PINNACLE	0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) static const struct alps_nibble_commands alps_v3_nibble_commands[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) 	{ PSMOUSE_CMD_SETPOLL,		0x00 }, /* 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) 	{ PSMOUSE_CMD_RESET_DIS,	0x00 }, /* 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) 	{ PSMOUSE_CMD_SETSCALE21,	0x00 }, /* 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) 	{ PSMOUSE_CMD_SETRATE,		0x0a }, /* 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) 	{ PSMOUSE_CMD_SETRATE,		0x14 }, /* 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) 	{ PSMOUSE_CMD_SETRATE,		0x28 }, /* 5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) 	{ PSMOUSE_CMD_SETRATE,		0x3c }, /* 6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) 	{ PSMOUSE_CMD_SETRATE,		0x50 }, /* 7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) 	{ PSMOUSE_CMD_SETRATE,		0x64 }, /* 8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) 	{ PSMOUSE_CMD_SETRATE,		0xc8 }, /* 9 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) 	{ ALPS_CMD_NIBBLE_10,		0x00 }, /* a */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) 	{ PSMOUSE_CMD_SETRES,		0x00 }, /* b */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) 	{ PSMOUSE_CMD_SETRES,		0x01 }, /* c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 	{ PSMOUSE_CMD_SETRES,		0x02 }, /* d */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) 	{ PSMOUSE_CMD_SETRES,		0x03 }, /* e */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) 	{ PSMOUSE_CMD_SETSCALE11,	0x00 }, /* f */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) static const struct alps_nibble_commands alps_v4_nibble_commands[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) 	{ PSMOUSE_CMD_ENABLE,		0x00 }, /* 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) 	{ PSMOUSE_CMD_RESET_DIS,	0x00 }, /* 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) 	{ PSMOUSE_CMD_SETSCALE21,	0x00 }, /* 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) 	{ PSMOUSE_CMD_SETRATE,		0x0a }, /* 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 	{ PSMOUSE_CMD_SETRATE,		0x14 }, /* 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) 	{ PSMOUSE_CMD_SETRATE,		0x28 }, /* 5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 	{ PSMOUSE_CMD_SETRATE,		0x3c }, /* 6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) 	{ PSMOUSE_CMD_SETRATE,		0x50 }, /* 7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) 	{ PSMOUSE_CMD_SETRATE,		0x64 }, /* 8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 	{ PSMOUSE_CMD_SETRATE,		0xc8 }, /* 9 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 	{ ALPS_CMD_NIBBLE_10,		0x00 }, /* a */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) 	{ PSMOUSE_CMD_SETRES,		0x00 }, /* b */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) 	{ PSMOUSE_CMD_SETRES,		0x01 }, /* c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 	{ PSMOUSE_CMD_SETRES,		0x02 }, /* d */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) 	{ PSMOUSE_CMD_SETRES,		0x03 }, /* e */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 	{ PSMOUSE_CMD_SETSCALE11,	0x00 }, /* f */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) static const struct alps_nibble_commands alps_v6_nibble_commands[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 	{ PSMOUSE_CMD_ENABLE,		0x00 }, /* 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 	{ PSMOUSE_CMD_SETRATE,		0x0a }, /* 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 	{ PSMOUSE_CMD_SETRATE,		0x14 }, /* 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 	{ PSMOUSE_CMD_SETRATE,		0x28 }, /* 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 	{ PSMOUSE_CMD_SETRATE,		0x3c }, /* 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 	{ PSMOUSE_CMD_SETRATE,		0x50 }, /* 5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 	{ PSMOUSE_CMD_SETRATE,		0x64 }, /* 6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 	{ PSMOUSE_CMD_SETRATE,		0xc8 }, /* 7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 	{ PSMOUSE_CMD_GETID,		0x00 }, /* 8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 	{ PSMOUSE_CMD_GETINFO,		0x00 }, /* 9 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 	{ PSMOUSE_CMD_SETRES,		0x00 }, /* a */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 	{ PSMOUSE_CMD_SETRES,		0x01 }, /* b */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 	{ PSMOUSE_CMD_SETRES,		0x02 }, /* c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 	{ PSMOUSE_CMD_SETRES,		0x03 }, /* d */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 	{ PSMOUSE_CMD_SETSCALE21,	0x00 }, /* e */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 	{ PSMOUSE_CMD_SETSCALE11,	0x00 }, /* f */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) #define ALPS_DUALPOINT		0x02	/* touchpad has trackstick */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) #define ALPS_PASS		0x04	/* device has a pass-through port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) #define ALPS_WHEEL		0x08	/* hardware wheel present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) #define ALPS_FW_BK_1		0x10	/* front & back buttons present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) #define ALPS_FW_BK_2		0x20	/* front & back buttons present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) #define ALPS_FOUR_BUTTONS	0x40	/* 4 direction button present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) #define ALPS_PS2_INTERLEAVED	0x80	/* 3-byte PS/2 packet interleaved with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 					   6-byte ALPS packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) #define ALPS_STICK_BITS		0x100	/* separate stick button bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) #define ALPS_BUTTONPAD		0x200	/* device is a clickpad */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) #define ALPS_DUALPOINT_WITH_PRESSURE	0x400	/* device can report trackpoint pressure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) static const struct alps_model_info alps_model_data[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 	 * XXX This entry is suspicious. First byte has zero lower nibble,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 	 * which is what a normal mouse would report. Also, the value 0x0e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 	 * isn't valid per PS/2 spec.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 	{ { 0x20, 0x02, 0x0e }, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 	{ { 0x22, 0x02, 0x0a }, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 	{ { 0x22, 0x02, 0x14 }, { ALPS_PROTO_V2, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT } },	/* Dell Latitude D600 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 	{ { 0x32, 0x02, 0x14 }, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT } },	/* Toshiba Salellite Pro M10 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 	{ { 0x33, 0x02, 0x0a }, { ALPS_PROTO_V1, 0x88, 0xf8, 0 } },				/* UMAX-530T */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 	{ { 0x52, 0x01, 0x14 }, { ALPS_PROTO_V2, 0xff, 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 		ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED } },				/* Toshiba Tecra A11-11L */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 	{ { 0x53, 0x02, 0x0a }, { ALPS_PROTO_V2, 0xf8, 0xf8, 0 } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 	{ { 0x53, 0x02, 0x14 }, { ALPS_PROTO_V2, 0xf8, 0xf8, 0 } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 	{ { 0x60, 0x03, 0xc8 }, { ALPS_PROTO_V2, 0xf8, 0xf8, 0 } },				/* HP ze1115 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 	{ { 0x62, 0x02, 0x14 }, { ALPS_PROTO_V2, 0xcf, 0xcf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 		ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED } },				/* Dell Latitude E5500, E6400, E6500, Precision M4400 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 	{ { 0x63, 0x02, 0x0a }, { ALPS_PROTO_V2, 0xf8, 0xf8, 0 } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 	{ { 0x63, 0x02, 0x14 }, { ALPS_PROTO_V2, 0xf8, 0xf8, 0 } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 	{ { 0x63, 0x02, 0x28 }, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_FW_BK_2 } },			/* Fujitsu Siemens S6010 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 	{ { 0x63, 0x02, 0x3c }, { ALPS_PROTO_V2, 0x8f, 0x8f, ALPS_WHEEL } },			/* Toshiba Satellite S2400-103 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 	{ { 0x63, 0x02, 0x50 }, { ALPS_PROTO_V2, 0xef, 0xef, ALPS_FW_BK_1 } },			/* NEC Versa L320 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 	{ { 0x63, 0x02, 0x64 }, { ALPS_PROTO_V2, 0xf8, 0xf8, 0 } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 	{ { 0x63, 0x03, 0xc8 }, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT } },	/* Dell Latitude D800 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	{ { 0x73, 0x00, 0x0a }, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_DUALPOINT } },		/* ThinkPad R61 8918-5QG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 	{ { 0x73, 0x00, 0x14 }, { ALPS_PROTO_V6, 0xff, 0xff, ALPS_DUALPOINT } },		/* Dell XT2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 	{ { 0x73, 0x02, 0x0a }, { ALPS_PROTO_V2, 0xf8, 0xf8, 0 } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 	{ { 0x73, 0x02, 0x14 }, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_FW_BK_2 } },			/* Ahtec Laptop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 	{ { 0x73, 0x02, 0x50 }, { ALPS_PROTO_V2, 0xcf, 0xcf, ALPS_FOUR_BUTTONS } },		/* Dell Vostro 1400 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) static const struct alps_protocol_info alps_v3_protocol_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 	ALPS_PROTO_V3, 0x8f, 0x8f, ALPS_DUALPOINT | ALPS_DUALPOINT_WITH_PRESSURE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) static const struct alps_protocol_info alps_v3_rushmore_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 	ALPS_PROTO_V3_RUSHMORE, 0x8f, 0x8f, ALPS_DUALPOINT | ALPS_DUALPOINT_WITH_PRESSURE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) static const struct alps_protocol_info alps_v4_protocol_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 	ALPS_PROTO_V4, 0x8f, 0x8f, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) static const struct alps_protocol_info alps_v5_protocol_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 	ALPS_PROTO_V5, 0xc8, 0xd8, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) static const struct alps_protocol_info alps_v7_protocol_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 	ALPS_PROTO_V7, 0x48, 0x48, ALPS_DUALPOINT | ALPS_DUALPOINT_WITH_PRESSURE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) static const struct alps_protocol_info alps_v8_protocol_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 	ALPS_PROTO_V8, 0x18, 0x18, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) static const struct alps_protocol_info alps_v9_protocol_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 	ALPS_PROTO_V9, 0xc8, 0xc8, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168)  * Some v2 models report the stick buttons in separate bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) static const struct dmi_system_id alps_dmi_has_separate_stick_buttons[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) #if defined(CONFIG_DMI) && defined(CONFIG_X86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 		/* Extrapolated from other entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 		.matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 			DMI_MATCH(DMI_PRODUCT_NAME, "Latitude D420"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 		/* Reported-by: Hans de Bruin <jmdebruin@xmsnet.nl> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 		.matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 			DMI_MATCH(DMI_PRODUCT_NAME, "Latitude D430"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 		/* Reported-by: Hans de Goede <hdegoede@redhat.com> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 		.matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 			DMI_MATCH(DMI_PRODUCT_NAME, "Latitude D620"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 		/* Extrapolated from other entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 		.matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 			DMI_MATCH(DMI_PRODUCT_NAME, "Latitude D630"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 	{ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) static void alps_set_abs_params_st(struct alps_data *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 				   struct input_dev *dev1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) static void alps_set_abs_params_semi_mt(struct alps_data *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 					struct input_dev *dev1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) static void alps_set_abs_params_v7(struct alps_data *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 				   struct input_dev *dev1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) static void alps_set_abs_params_ss4_v2(struct alps_data *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 				       struct input_dev *dev1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) /* Packet formats are described in Documentation/input/devices/alps.rst */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) static bool alps_is_valid_first_byte(struct alps_data *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 				     unsigned char data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 	return (data & priv->mask0) == priv->byte0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) static void alps_report_buttons(struct input_dev *dev1, struct input_dev *dev2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 				int left, int right, int middle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 	struct input_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 	 * If shared button has already been reported on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 	 * other device (dev2) then this event should be also
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 	 * sent through that device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 	dev = (dev2 && test_bit(BTN_LEFT, dev2->key)) ? dev2 : dev1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 	input_report_key(dev, BTN_LEFT, left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 	dev = (dev2 && test_bit(BTN_RIGHT, dev2->key)) ? dev2 : dev1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 	input_report_key(dev, BTN_RIGHT, right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 	dev = (dev2 && test_bit(BTN_MIDDLE, dev2->key)) ? dev2 : dev1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 	input_report_key(dev, BTN_MIDDLE, middle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 	 * Sync the _other_ device now, we'll do the first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 	 * device later once we report the rest of the events.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 	if (dev2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 		input_sync(dev2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) static void alps_process_packet_v1_v2(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 	struct alps_data *priv = psmouse->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 	unsigned char *packet = psmouse->packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 	struct input_dev *dev = psmouse->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 	struct input_dev *dev2 = priv->dev2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 	int x, y, z, ges, fin, left, right, middle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 	int back = 0, forward = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 	if (priv->proto_version == ALPS_PROTO_V1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 		left = packet[2] & 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 		right = packet[2] & 0x08;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 		middle = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 		x = packet[1] | ((packet[0] & 0x07) << 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 		y = packet[4] | ((packet[3] & 0x07) << 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 		z = packet[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 		left = packet[3] & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 		right = packet[3] & 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 		middle = packet[3] & 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 		x = packet[1] | ((packet[2] & 0x78) << (7 - 3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 		y = packet[4] | ((packet[3] & 0x70) << (7 - 4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 		z = packet[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 	if (priv->flags & ALPS_FW_BK_1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 		back = packet[0] & 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 		forward = packet[2] & 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 	if (priv->flags & ALPS_FW_BK_2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 		back = packet[3] & 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 		forward = packet[2] & 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 		if ((middle = forward && back))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 			forward = back = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 	ges = packet[2] & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 	fin = packet[2] & 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 	if ((priv->flags & ALPS_DUALPOINT) && z == 127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 		input_report_rel(dev2, REL_X,  (x > 383 ? (x - 768) : x));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 		input_report_rel(dev2, REL_Y, -(y > 255 ? (y - 512) : y));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 		alps_report_buttons(dev2, dev, left, right, middle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 		input_sync(dev2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 	/* Some models have separate stick button bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 	if (priv->flags & ALPS_STICK_BITS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 		left |= packet[0] & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 		right |= packet[0] & 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 		middle |= packet[0] & 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 	alps_report_buttons(dev, dev2, left, right, middle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 	/* Convert hardware tap to a reasonable Z value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 	if (ges && !fin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 		z = 40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 	 * A "tap and drag" operation is reported by the hardware as a transition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 	 * from (!fin && ges) to (fin && ges). This should be translated to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 	 * sequence Z>0, Z==0, Z>0, so the Z==0 event has to be generated manually.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 	if (ges && fin && !priv->prev_fin) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 		input_report_abs(dev, ABS_X, x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 		input_report_abs(dev, ABS_Y, y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 		input_report_abs(dev, ABS_PRESSURE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 		input_report_key(dev, BTN_TOOL_FINGER, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 		input_sync(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 	priv->prev_fin = fin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 	if (z > 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 		input_report_key(dev, BTN_TOUCH, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 	if (z < 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 		input_report_key(dev, BTN_TOUCH, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 	if (z > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 		input_report_abs(dev, ABS_X, x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 		input_report_abs(dev, ABS_Y, y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 	input_report_abs(dev, ABS_PRESSURE, z);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 	input_report_key(dev, BTN_TOOL_FINGER, z > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 	if (priv->flags & ALPS_WHEEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 		input_report_rel(dev, REL_WHEEL, ((packet[2] << 1) & 0x08) - ((packet[0] >> 4) & 0x07));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 	if (priv->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 		input_report_key(dev, BTN_FORWARD, forward);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 		input_report_key(dev, BTN_BACK, back);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 	if (priv->flags & ALPS_FOUR_BUTTONS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 		input_report_key(dev, BTN_0, packet[2] & 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 		input_report_key(dev, BTN_1, packet[0] & 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 		input_report_key(dev, BTN_2, packet[3] & 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 		input_report_key(dev, BTN_3, packet[0] & 0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 	input_sync(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) static void alps_get_bitmap_points(unsigned int map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 				   struct alps_bitmap_point *low,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 				   struct alps_bitmap_point *high,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 				   int *fingers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 	struct alps_bitmap_point *point;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 	int i, bit, prev_bit = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 	point = low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 	for (i = 0; map != 0; i++, map >>= 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 		bit = map & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 		if (bit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 			if (!prev_bit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 				point->start_bit = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 				point->num_bits = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 				(*fingers)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 			point->num_bits++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 			if (prev_bit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 				point = high;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 		prev_bit = bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383)  * Process bitmap data from semi-mt protocols. Returns the number of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384)  * fingers detected. A return value of 0 means at least one of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385)  * bitmaps was empty.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387)  * The bitmaps don't have enough data to track fingers, so this function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388)  * only generates points representing a bounding box of all contacts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389)  * These points are returned in fields->mt when the return value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390)  * is greater than 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) static int alps_process_bitmap(struct alps_data *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 			       struct alps_fields *fields)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 	int i, fingers_x = 0, fingers_y = 0, fingers, closest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 	struct alps_bitmap_point x_low = {0,}, x_high = {0,};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 	struct alps_bitmap_point y_low = {0,}, y_high = {0,};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 	struct input_mt_pos corner[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 	if (!fields->x_map || !fields->y_map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 	alps_get_bitmap_points(fields->x_map, &x_low, &x_high, &fingers_x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 	alps_get_bitmap_points(fields->y_map, &y_low, &y_high, &fingers_y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 	 * Fingers can overlap, so we use the maximum count of fingers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 	 * on either axis as the finger count.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 	fingers = max(fingers_x, fingers_y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 	 * If an axis reports only a single contact, we have overlapping or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 	 * adjacent fingers. Divide the single contact between the two points.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 	if (fingers_x == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 		i = (x_low.num_bits - 1) / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 		x_low.num_bits = x_low.num_bits - i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 		x_high.start_bit = x_low.start_bit + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 		x_high.num_bits = max(i, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 	if (fingers_y == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 		i = (y_low.num_bits - 1) / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 		y_low.num_bits = y_low.num_bits - i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 		y_high.start_bit = y_low.start_bit + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 		y_high.num_bits = max(i, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 	/* top-left corner */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 	corner[0].x =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 		(priv->x_max * (2 * x_low.start_bit + x_low.num_bits - 1)) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 		(2 * (priv->x_bits - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 	corner[0].y =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 		(priv->y_max * (2 * y_low.start_bit + y_low.num_bits - 1)) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 		(2 * (priv->y_bits - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 	/* top-right corner */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 	corner[1].x =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 		(priv->x_max * (2 * x_high.start_bit + x_high.num_bits - 1)) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 		(2 * (priv->x_bits - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 	corner[1].y =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 		(priv->y_max * (2 * y_low.start_bit + y_low.num_bits - 1)) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 		(2 * (priv->y_bits - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 	/* bottom-right corner */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 	corner[2].x =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 		(priv->x_max * (2 * x_high.start_bit + x_high.num_bits - 1)) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 		(2 * (priv->x_bits - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 	corner[2].y =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 		(priv->y_max * (2 * y_high.start_bit + y_high.num_bits - 1)) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 		(2 * (priv->y_bits - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 	/* bottom-left corner */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 	corner[3].x =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 		(priv->x_max * (2 * x_low.start_bit + x_low.num_bits - 1)) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 		(2 * (priv->x_bits - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 	corner[3].y =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 		(priv->y_max * (2 * y_high.start_bit + y_high.num_bits - 1)) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 		(2 * (priv->y_bits - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 	/* x-bitmap order is reversed on v5 touchpads  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 	if (priv->proto_version == ALPS_PROTO_V5) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 		for (i = 0; i < 4; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 			corner[i].x = priv->x_max - corner[i].x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 	/* y-bitmap order is reversed on v3 and v4 touchpads  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 	if (priv->proto_version == ALPS_PROTO_V3 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 	    priv->proto_version == ALPS_PROTO_V4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 		for (i = 0; i < 4; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 			corner[i].y = priv->y_max - corner[i].y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 	 * We only select a corner for the second touch once per 2 finger
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 	 * touch sequence to avoid the chosen corner (and thus the coordinates)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 	 * jumping around when the first touch is in the middle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 	if (priv->second_touch == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 		/* Find corner closest to our st coordinates */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 		closest = 0x7fffffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 		for (i = 0; i < 4; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 			int dx = fields->st.x - corner[i].x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 			int dy = fields->st.y - corner[i].y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 			int distance = dx * dx + dy * dy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 			if (distance < closest) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 				priv->second_touch = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 				closest = distance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 		/* And select the opposite corner to use for the 2nd touch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 		priv->second_touch = (priv->second_touch + 2) % 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 	fields->mt[0] = fields->st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 	fields->mt[1] = corner[priv->second_touch];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 	return fingers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) static void alps_set_slot(struct input_dev *dev, int slot, int x, int y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 	input_mt_slot(dev, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 	input_mt_report_slot_state(dev, MT_TOOL_FINGER, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 	input_report_abs(dev, ABS_MT_POSITION_X, x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 	input_report_abs(dev, ABS_MT_POSITION_Y, y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) static void alps_report_mt_data(struct psmouse *psmouse, int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 	struct alps_data *priv = psmouse->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 	struct input_dev *dev = psmouse->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 	struct alps_fields *f = &priv->f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 	int i, slot[MAX_TOUCHES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 	input_mt_assign_slots(dev, slot, f->mt, n, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 	for (i = 0; i < n; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 		alps_set_slot(dev, slot[i], f->mt[i].x, f->mt[i].y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 	input_mt_sync_frame(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) static void alps_report_semi_mt_data(struct psmouse *psmouse, int fingers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 	struct alps_data *priv = psmouse->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 	struct input_dev *dev = psmouse->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 	struct alps_fields *f = &priv->f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 	/* Use st data when we don't have mt data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 	if (fingers < 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 		f->mt[0].x = f->st.x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 		f->mt[0].y = f->st.y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 		fingers = f->pressure > 0 ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 		priv->second_touch = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 	if (fingers >= 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 		alps_set_slot(dev, 0, f->mt[0].x, f->mt[0].y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 	if (fingers >= 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 		alps_set_slot(dev, 1, f->mt[1].x, f->mt[1].y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 	input_mt_sync_frame(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 	input_mt_report_finger_count(dev, fingers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 	input_report_key(dev, BTN_LEFT, f->left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 	input_report_key(dev, BTN_RIGHT, f->right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 	input_report_key(dev, BTN_MIDDLE, f->middle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 	input_report_abs(dev, ABS_PRESSURE, f->pressure);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 	input_sync(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) static void alps_process_trackstick_packet_v3(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 	struct alps_data *priv = psmouse->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 	unsigned char *packet = psmouse->packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 	struct input_dev *dev = priv->dev2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 	int x, y, z, left, right, middle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 	/* It should be a DualPoint when received trackstick packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 	if (!(priv->flags & ALPS_DUALPOINT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 		psmouse_warn(psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 			     "Rejected trackstick packet from non DualPoint device");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 	/* Sanity check packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	if (!(packet[0] & 0x40)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 		psmouse_dbg(psmouse, "Bad trackstick packet, discarding\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 	 * There's a special packet that seems to indicate the end
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 	 * of a stream of trackstick data. Filter these out.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	if (packet[1] == 0x7f && packet[2] == 0x7f && packet[4] == 0x7f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 	x = (s8)(((packet[0] & 0x20) << 2) | (packet[1] & 0x7f));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 	y = (s8)(((packet[0] & 0x10) << 3) | (packet[2] & 0x7f));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 	z = packet[4] & 0x7f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 	 * The x and y values tend to be quite large, and when used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 	 * alone the trackstick is difficult to use. Scale them down
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	 * to compensate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 	x /= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 	y /= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 	input_report_rel(dev, REL_X, x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 	input_report_rel(dev, REL_Y, -y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 	input_report_abs(dev, ABS_PRESSURE, z);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 	 * Most ALPS models report the trackstick buttons in the touchpad
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 	 * packets, but a few report them here. No reliable way has been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 	 * found to differentiate between the models upfront, so we enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 	 * the quirk in response to seeing a button press in the trackstick
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 	 * packet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 	left = packet[3] & 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 	right = packet[3] & 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 	middle = packet[3] & 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 	if (!(priv->quirks & ALPS_QUIRK_TRACKSTICK_BUTTONS) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 	    (left || right || middle))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 		priv->quirks |= ALPS_QUIRK_TRACKSTICK_BUTTONS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 	if (priv->quirks & ALPS_QUIRK_TRACKSTICK_BUTTONS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 		input_report_key(dev, BTN_LEFT, left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 		input_report_key(dev, BTN_RIGHT, right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 		input_report_key(dev, BTN_MIDDLE, middle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 	input_sync(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) static void alps_decode_buttons_v3(struct alps_fields *f, unsigned char *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 	f->left = !!(p[3] & 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 	f->right = !!(p[3] & 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 	f->middle = !!(p[3] & 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 	f->ts_left = !!(p[3] & 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 	f->ts_right = !!(p[3] & 0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 	f->ts_middle = !!(p[3] & 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) static int alps_decode_pinnacle(struct alps_fields *f, unsigned char *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 				 struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 	f->first_mp = !!(p[4] & 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 	f->is_mp = !!(p[0] & 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 	if (f->is_mp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 		f->fingers = (p[5] & 0x3) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 		f->x_map = ((p[4] & 0x7e) << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 			   ((p[1] & 0x7f) << 2) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 			   ((p[0] & 0x30) >> 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 		f->y_map = ((p[3] & 0x70) << 4) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 			   ((p[2] & 0x7f) << 1) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 			   (p[4] & 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 		f->st.x = ((p[1] & 0x7f) << 4) | ((p[4] & 0x30) >> 2) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 		       ((p[0] & 0x30) >> 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 		f->st.y = ((p[2] & 0x7f) << 4) | (p[4] & 0x0f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 		f->pressure = p[5] & 0x7f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 		alps_decode_buttons_v3(f, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) static int alps_decode_rushmore(struct alps_fields *f, unsigned char *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 				 struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 	f->first_mp = !!(p[4] & 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 	f->is_mp = !!(p[5] & 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 	if (f->is_mp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 		f->fingers = max((p[5] & 0x3), ((p[5] >> 2) & 0x3)) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 		f->x_map = ((p[5] & 0x10) << 11) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 			   ((p[4] & 0x7e) << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 			   ((p[1] & 0x7f) << 2) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 			   ((p[0] & 0x30) >> 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 		f->y_map = ((p[5] & 0x20) << 6) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 			   ((p[3] & 0x70) << 4) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 			   ((p[2] & 0x7f) << 1) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 			   (p[4] & 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 		f->st.x = ((p[1] & 0x7f) << 4) | ((p[4] & 0x30) >> 2) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 		       ((p[0] & 0x30) >> 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 		f->st.y = ((p[2] & 0x7f) << 4) | (p[4] & 0x0f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 		f->pressure = p[5] & 0x7f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 		alps_decode_buttons_v3(f, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) static int alps_decode_dolphin(struct alps_fields *f, unsigned char *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 				struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 	u64 palm_data = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 	struct alps_data *priv = psmouse->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 	f->first_mp = !!(p[0] & 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 	f->is_mp = !!(p[0] & 0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 	if (!f->is_mp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 		f->st.x = ((p[1] & 0x7f) | ((p[4] & 0x0f) << 7));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 		f->st.y = ((p[2] & 0x7f) | ((p[4] & 0xf0) << 3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 		f->pressure = (p[0] & 4) ? 0 : p[5] & 0x7f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 		alps_decode_buttons_v3(f, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 		f->fingers = ((p[0] & 0x6) >> 1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 		     (p[0] & 0x10) >> 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 		palm_data = (p[1] & 0x7f) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 			    ((p[2] & 0x7f) << 7) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 			    ((p[4] & 0x7f) << 14) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 			    ((p[5] & 0x7f) << 21) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 			    ((p[3] & 0x07) << 28) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 			    (((u64)p[3] & 0x70) << 27) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 			    (((u64)p[0] & 0x01) << 34);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 		/* Y-profile is stored in P(0) to p(n-1), n = y_bits; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 		f->y_map = palm_data & (BIT(priv->y_bits) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 		/* X-profile is stored in p(n) to p(n+m-1), m = x_bits; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 		f->x_map = (palm_data >> priv->y_bits) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 			   (BIT(priv->x_bits) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) static void alps_process_touchpad_packet_v3_v5(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 	struct alps_data *priv = psmouse->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 	unsigned char *packet = psmouse->packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 	struct input_dev *dev2 = priv->dev2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 	struct alps_fields *f = &priv->f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 	int fingers = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 	memset(f, 0, sizeof(*f));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 	priv->decode_fields(f, packet, psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 	 * There's no single feature of touchpad position and bitmap packets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 	 * that can be used to distinguish between them. We rely on the fact
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 	 * that a bitmap packet should always follow a position packet with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 	 * bit 6 of packet[4] set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 	if (priv->multi_packet) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 		 * Sometimes a position packet will indicate a multi-packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 		 * sequence, but then what follows is another position
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 		 * packet. Check for this, and when it happens process the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 		 * position packet as usual.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 		if (f->is_mp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 			fingers = f->fingers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 			 * Bitmap processing uses position packet's coordinate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 			 * data, so we need to do decode it first.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 			priv->decode_fields(f, priv->multi_data, psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 			if (alps_process_bitmap(priv, f) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 				fingers = 0; /* Use st data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 			priv->multi_packet = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 	 * Bit 6 of byte 0 is not usually set in position packets. The only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 	 * times it seems to be set is in situations where the data is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 	 * suspect anyway, e.g. a palm resting flat on the touchpad. Given
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 	 * this combined with the fact that this bit is useful for filtering
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 	 * out misidentified bitmap packets, we reject anything with this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 	 * bit set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 	if (f->is_mp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 	if (!priv->multi_packet && f->first_mp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 		priv->multi_packet = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 		memcpy(priv->multi_data, packet, sizeof(priv->multi_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 	priv->multi_packet = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 	 * Sometimes the hardware sends a single packet with z = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 	 * in the middle of a stream. Real releases generate packets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 	 * with x, y, and z all zero, so these seem to be flukes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 	 * Ignore them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 	if (f->st.x && f->st.y && !f->pressure)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 	alps_report_semi_mt_data(psmouse, fingers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 	if ((priv->flags & ALPS_DUALPOINT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 	    !(priv->quirks & ALPS_QUIRK_TRACKSTICK_BUTTONS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 		input_report_key(dev2, BTN_LEFT, f->ts_left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 		input_report_key(dev2, BTN_RIGHT, f->ts_right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 		input_report_key(dev2, BTN_MIDDLE, f->ts_middle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 		input_sync(dev2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) static void alps_process_packet_v3(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 	unsigned char *packet = psmouse->packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 	 * v3 protocol packets come in three types, two representing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 	 * touchpad data and one representing trackstick data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 	 * Trackstick packets seem to be distinguished by always
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 	 * having 0x3f in the last byte. This value has never been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 	 * observed in the last byte of either of the other types
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 	 * of packets.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 	if (packet[5] == 0x3f) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 		alps_process_trackstick_packet_v3(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 	alps_process_touchpad_packet_v3_v5(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) static void alps_process_packet_v6(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 	struct alps_data *priv = psmouse->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 	unsigned char *packet = psmouse->packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 	struct input_dev *dev = psmouse->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 	struct input_dev *dev2 = priv->dev2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 	int x, y, z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 	 * We can use Byte5 to distinguish if the packet is from Touchpad
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 	 * or Trackpoint.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 	 * Touchpad:	0 - 0x7E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 	 * Trackpoint:	0x7F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 	if (packet[5] == 0x7F) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 		/* It should be a DualPoint when received Trackpoint packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 		if (!(priv->flags & ALPS_DUALPOINT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 			psmouse_warn(psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 				     "Rejected trackstick packet from non DualPoint device");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 		/* Trackpoint packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 		x = packet[1] | ((packet[3] & 0x20) << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 		y = packet[2] | ((packet[3] & 0x40) << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 		z = packet[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 		/* To prevent the cursor jump when finger lifted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 		if (x == 0x7F && y == 0x7F && z == 0x7F)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 			x = y = z = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 		/* Divide 4 since trackpoint's speed is too fast */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 		input_report_rel(dev2, REL_X, (char)x / 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 		input_report_rel(dev2, REL_Y, -((char)y / 4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 		psmouse_report_standard_buttons(dev2, packet[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 		input_sync(dev2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 	/* Touchpad packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 	x = packet[1] | ((packet[3] & 0x78) << 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 	y = packet[2] | ((packet[4] & 0x78) << 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 	z = packet[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 	if (z > 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 		input_report_key(dev, BTN_TOUCH, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 	if (z < 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 		input_report_key(dev, BTN_TOUCH, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 	if (z > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 		input_report_abs(dev, ABS_X, x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 		input_report_abs(dev, ABS_Y, y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 	input_report_abs(dev, ABS_PRESSURE, z);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 	input_report_key(dev, BTN_TOOL_FINGER, z > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 	/* v6 touchpad does not have middle button */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 	packet[3] &= ~BIT(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 	psmouse_report_standard_buttons(dev2, packet[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 	input_sync(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) static void alps_process_packet_v4(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 	struct alps_data *priv = psmouse->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 	unsigned char *packet = psmouse->packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 	struct alps_fields *f = &priv->f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 	int offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 	 * v4 has a 6-byte encoding for bitmap data, but this data is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 	 * broken up between 3 normal packets. Use priv->multi_packet to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 	 * track our position in the bitmap packet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 	if (packet[6] & 0x40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 		/* sync, reset position */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 		priv->multi_packet = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 	if (WARN_ON_ONCE(priv->multi_packet > 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 	offset = 2 * priv->multi_packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 	priv->multi_data[offset] = packet[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 	priv->multi_data[offset + 1] = packet[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 	f->left = !!(packet[4] & 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 	f->right = !!(packet[4] & 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 	f->st.x = ((packet[1] & 0x7f) << 4) | ((packet[3] & 0x30) >> 2) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 		  ((packet[0] & 0x30) >> 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 	f->st.y = ((packet[2] & 0x7f) << 4) | (packet[3] & 0x0f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 	f->pressure = packet[5] & 0x7f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 	if (++priv->multi_packet > 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 		priv->multi_packet = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 		f->x_map = ((priv->multi_data[2] & 0x1f) << 10) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 			   ((priv->multi_data[3] & 0x60) << 3) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 			   ((priv->multi_data[0] & 0x3f) << 2) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 			   ((priv->multi_data[1] & 0x60) >> 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 		f->y_map = ((priv->multi_data[5] & 0x01) << 10) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 			   ((priv->multi_data[3] & 0x1f) << 5) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 			    (priv->multi_data[1] & 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 		f->fingers = alps_process_bitmap(priv, f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 	alps_report_semi_mt_data(psmouse, f->fingers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) static bool alps_is_valid_package_v7(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 	switch (psmouse->pktcnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 	case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 		return (psmouse->packet[2] & 0x40) == 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 	case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 		return (psmouse->packet[3] & 0x48) == 0x48;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 	case 6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 		return (psmouse->packet[5] & 0x40) == 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) static unsigned char alps_get_packet_id_v7(char *byte)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 	unsigned char packet_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 	if (byte[4] & 0x40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 		packet_id = V7_PACKET_ID_TWO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 	else if (byte[4] & 0x01)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 		packet_id = V7_PACKET_ID_MULTI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 	else if ((byte[0] & 0x10) && !(byte[4] & 0x43))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 		packet_id = V7_PACKET_ID_NEW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	else if (byte[1] == 0x00 && byte[4] == 0x00)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 		packet_id = V7_PACKET_ID_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 		packet_id = V7_PACKET_ID_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 	return packet_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) static void alps_get_finger_coordinate_v7(struct input_mt_pos *mt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 					  unsigned char *pkt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 					  unsigned char pkt_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 	mt[0].x = ((pkt[2] & 0x80) << 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 	mt[0].x |= ((pkt[2] & 0x3F) << 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 	mt[0].x |= ((pkt[3] & 0x30) >> 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 	mt[0].x |= (pkt[3] & 0x07);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 	mt[0].y = (pkt[1] << 3) | (pkt[0] & 0x07);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 	mt[1].x = ((pkt[3] & 0x80) << 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	mt[1].x |= ((pkt[4] & 0x80) << 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 	mt[1].x |= ((pkt[4] & 0x3F) << 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 	mt[1].y = ((pkt[5] & 0x80) << 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	mt[1].y |= ((pkt[5] & 0x3F) << 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	switch (pkt_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 	case V7_PACKET_ID_TWO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 		mt[1].x &= ~0x000F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 		mt[1].y |= 0x000F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 		/* Detect false-postive touches where x & y report max value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 		if (mt[1].y == 0x7ff && mt[1].x == 0xff0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 			mt[1].x = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 			/* y gets set to 0 at the end of this function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 	case V7_PACKET_ID_MULTI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 		mt[1].x &= ~0x003F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 		mt[1].y &= ~0x0020;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 		mt[1].y |= ((pkt[4] & 0x02) << 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 		mt[1].y |= 0x001F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 	case V7_PACKET_ID_NEW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 		mt[1].x &= ~0x003F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 		mt[1].x |= (pkt[0] & 0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 		mt[1].y |= 0x000F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 	mt[0].y = 0x7FF - mt[0].y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 	mt[1].y = 0x7FF - mt[1].y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) static int alps_get_mt_count(struct input_mt_pos *mt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 	int i, fingers = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 	for (i = 0; i < MAX_TOUCHES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 		if (mt[i].x != 0 || mt[i].y != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 			fingers++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 	return fingers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) static int alps_decode_packet_v7(struct alps_fields *f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 				  unsigned char *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 				  struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 	struct alps_data *priv = psmouse->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	unsigned char pkt_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 	pkt_id = alps_get_packet_id_v7(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 	if (pkt_id == V7_PACKET_ID_IDLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 	if (pkt_id == V7_PACKET_ID_UNKNOWN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 	 * NEW packets are send to indicate a discontinuity in the finger
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 	 * coordinate reporting. Specifically a finger may have moved from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 	 * slot 0 to 1 or vice versa. INPUT_MT_TRACK takes care of this for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 	 * us.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 	 * NEW packets have 3 problems:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 	 * 1) They do not contain middle / right button info (on non clickpads)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 	 *    this can be worked around by preserving the old button state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 	 * 2) They do not contain an accurate fingercount, and they are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 	 *    typically send when the number of fingers changes. We cannot use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 	 *    the old finger count as that may mismatch with the amount of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 	 *    touch coordinates we've available in the NEW packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 	 * 3) Their x data for the second touch is inaccurate leading to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 	 *    a possible jump of the x coordinate by 16 units when the first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 	 *    non NEW packet comes in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 	 * Since problems 2 & 3 cannot be worked around, just ignore them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 	if (pkt_id == V7_PACKET_ID_NEW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 	alps_get_finger_coordinate_v7(f->mt, p, pkt_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 	if (pkt_id == V7_PACKET_ID_TWO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 		f->fingers = alps_get_mt_count(f->mt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 	else /* pkt_id == V7_PACKET_ID_MULTI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 		f->fingers = 3 + (p[5] & 0x03);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 	f->left = (p[0] & 0x80) >> 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 	if (priv->flags & ALPS_BUTTONPAD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 		if (p[0] & 0x20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 			f->fingers++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 		if (p[0] & 0x10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 			f->fingers++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 		f->right = (p[0] & 0x20) >> 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 		f->middle = (p[0] & 0x10) >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 	/* Sometimes a single touch is reported in mt[1] rather then mt[0] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 	if (f->fingers == 1 && f->mt[0].x == 0 && f->mt[0].y == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 		f->mt[0].x = f->mt[1].x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 		f->mt[0].y = f->mt[1].y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 		f->mt[1].x = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 		f->mt[1].y = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) static void alps_process_trackstick_packet_v7(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 	struct alps_data *priv = psmouse->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 	unsigned char *packet = psmouse->packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 	struct input_dev *dev2 = priv->dev2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 	int x, y, z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 	/* It should be a DualPoint when received trackstick packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 	if (!(priv->flags & ALPS_DUALPOINT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 		psmouse_warn(psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 			     "Rejected trackstick packet from non DualPoint device");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 	x = ((packet[2] & 0xbf)) | ((packet[3] & 0x10) << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 	y = (packet[3] & 0x07) | (packet[4] & 0xb8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 	    ((packet[3] & 0x20) << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 	z = (packet[5] & 0x3f) | ((packet[3] & 0x80) >> 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 	input_report_rel(dev2, REL_X, (char)x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 	input_report_rel(dev2, REL_Y, -((char)y));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 	input_report_abs(dev2, ABS_PRESSURE, z);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 	psmouse_report_standard_buttons(dev2, packet[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 	input_sync(dev2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) static void alps_process_touchpad_packet_v7(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 	struct alps_data *priv = psmouse->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 	struct input_dev *dev = psmouse->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 	struct alps_fields *f = &priv->f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 	memset(f, 0, sizeof(*f));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 	if (priv->decode_fields(f, psmouse->packet, psmouse))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 	alps_report_mt_data(psmouse, alps_get_mt_count(f->mt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 	input_mt_report_finger_count(dev, f->fingers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 	input_report_key(dev, BTN_LEFT, f->left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 	input_report_key(dev, BTN_RIGHT, f->right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 	input_report_key(dev, BTN_MIDDLE, f->middle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 	input_sync(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) static void alps_process_packet_v7(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 	unsigned char *packet = psmouse->packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 	if (packet[0] == 0x48 && (packet[4] & 0x47) == 0x06)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 		alps_process_trackstick_packet_v7(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 		alps_process_touchpad_packet_v7(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) static enum SS4_PACKET_ID alps_get_pkt_id_ss4_v2(unsigned char *byte)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 	enum SS4_PACKET_ID pkt_id = SS4_PACKET_ID_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 	switch (byte[3] & 0x30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 	case 0x00:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 		if (SS4_IS_IDLE_V2(byte)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 			pkt_id = SS4_PACKET_ID_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 			pkt_id = SS4_PACKET_ID_ONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 	case 0x10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 		/* two-finger finger positions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 		pkt_id = SS4_PACKET_ID_TWO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 	case 0x20:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 		/* stick pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 		pkt_id = SS4_PACKET_ID_STICK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 	case 0x30:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 		/* third and fourth finger positions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 		pkt_id = SS4_PACKET_ID_MULTI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 	return pkt_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) static int alps_decode_ss4_v2(struct alps_fields *f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 			      unsigned char *p, struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 	struct alps_data *priv = psmouse->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 	enum SS4_PACKET_ID pkt_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 	unsigned int no_data_x, no_data_y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 	pkt_id = alps_get_pkt_id_ss4_v2(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 	/* Current packet is 1Finger coordinate packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 	switch (pkt_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 	case SS4_PACKET_ID_ONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 		f->mt[0].x = SS4_1F_X_V2(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 		f->mt[0].y = SS4_1F_Y_V2(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 		f->pressure = ((SS4_1F_Z_V2(p)) * 2) & 0x7f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 		 * When a button is held the device will give us events
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 		 * with x, y, and pressure of 0. This causes annoying jumps
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 		 * if a touch is released while the button is held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 		 * Handle this by claiming zero contacts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 		f->fingers = f->pressure > 0 ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 		f->first_mp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 		f->is_mp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 	case SS4_PACKET_ID_TWO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 		if (priv->flags & ALPS_BUTTONPAD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 			if (IS_SS4PLUS_DEV(priv->dev_id)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 				f->mt[0].x = SS4_PLUS_BTL_MF_X_V2(p, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 				f->mt[1].x = SS4_PLUS_BTL_MF_X_V2(p, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 				f->mt[0].x = SS4_BTL_MF_X_V2(p, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 				f->mt[1].x = SS4_BTL_MF_X_V2(p, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 			f->mt[0].y = SS4_BTL_MF_Y_V2(p, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 			f->mt[1].y = SS4_BTL_MF_Y_V2(p, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 			if (IS_SS4PLUS_DEV(priv->dev_id)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 				f->mt[0].x = SS4_PLUS_STD_MF_X_V2(p, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 				f->mt[1].x = SS4_PLUS_STD_MF_X_V2(p, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 				f->mt[0].x = SS4_STD_MF_X_V2(p, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 				f->mt[1].x = SS4_STD_MF_X_V2(p, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 			f->mt[0].y = SS4_STD_MF_Y_V2(p, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 			f->mt[1].y = SS4_STD_MF_Y_V2(p, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 		f->pressure = SS4_MF_Z_V2(p, 0) ? 0x30 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 		if (SS4_IS_MF_CONTINUE(p)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 			f->first_mp = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 			f->fingers = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 			f->first_mp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 		f->is_mp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 	case SS4_PACKET_ID_MULTI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 		if (priv->flags & ALPS_BUTTONPAD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 			if (IS_SS4PLUS_DEV(priv->dev_id)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 				f->mt[2].x = SS4_PLUS_BTL_MF_X_V2(p, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 				f->mt[3].x = SS4_PLUS_BTL_MF_X_V2(p, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 				no_data_x = SS4_PLUS_MFPACKET_NO_AX_BL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 				f->mt[2].x = SS4_BTL_MF_X_V2(p, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 				f->mt[3].x = SS4_BTL_MF_X_V2(p, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 				no_data_x = SS4_MFPACKET_NO_AX_BL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 			no_data_y = SS4_MFPACKET_NO_AY_BL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 			f->mt[2].y = SS4_BTL_MF_Y_V2(p, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 			f->mt[3].y = SS4_BTL_MF_Y_V2(p, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 			if (IS_SS4PLUS_DEV(priv->dev_id)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 				f->mt[2].x = SS4_PLUS_STD_MF_X_V2(p, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 				f->mt[3].x = SS4_PLUS_STD_MF_X_V2(p, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 				no_data_x = SS4_PLUS_MFPACKET_NO_AX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 				f->mt[2].x = SS4_STD_MF_X_V2(p, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 				f->mt[3].x = SS4_STD_MF_X_V2(p, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 				no_data_x = SS4_MFPACKET_NO_AX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 			no_data_y = SS4_MFPACKET_NO_AY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 			f->mt[2].y = SS4_STD_MF_Y_V2(p, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 			f->mt[3].y = SS4_STD_MF_Y_V2(p, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 		f->first_mp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 		f->is_mp = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 		if (SS4_IS_5F_DETECTED(p)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 			f->fingers = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 		} else if (f->mt[3].x == no_data_x &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 			     f->mt[3].y == no_data_y) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 			f->mt[3].x = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 			f->mt[3].y = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 			f->fingers = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 			f->fingers = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 	case SS4_PACKET_ID_STICK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 		 * x, y, and pressure are decoded in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 		 * alps_process_packet_ss4_v2()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 		f->first_mp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 		f->is_mp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 	case SS4_PACKET_ID_IDLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 		memset(f, 0, sizeof(struct alps_fields));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 	/* handle buttons */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 	if (pkt_id == SS4_PACKET_ID_STICK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 		f->ts_left = !!(SS4_BTN_V2(p) & 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 		f->ts_right = !!(SS4_BTN_V2(p) & 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 		f->ts_middle = !!(SS4_BTN_V2(p) & 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) 		f->left = !!(SS4_BTN_V2(p) & 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 		if (!(priv->flags & ALPS_BUTTONPAD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 			f->right = !!(SS4_BTN_V2(p) & 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 			f->middle = !!(SS4_BTN_V2(p) & 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) static void alps_process_packet_ss4_v2(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 	struct alps_data *priv = psmouse->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 	unsigned char *packet = psmouse->packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 	struct input_dev *dev = psmouse->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 	struct input_dev *dev2 = priv->dev2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 	struct alps_fields *f = &priv->f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 	memset(f, 0, sizeof(struct alps_fields));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 	priv->decode_fields(f, packet, psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 	if (priv->multi_packet) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 		 * Sometimes the first packet will indicate a multi-packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 		 * sequence, but sometimes the next multi-packet would not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 		 * come. Check for this, and when it happens process the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 		 * position packet as usual.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 		if (f->is_mp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 			/* Now process the 1st packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 			priv->decode_fields(f, priv->multi_data, psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 			priv->multi_packet = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 	 * "f.is_mp" would always be '0' after merging the 1st and 2nd packet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 	 * When it is set, it means 2nd packet comes without 1st packet come.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 	if (f->is_mp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 	/* Save the first packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 	if (!priv->multi_packet && f->first_mp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 		priv->multi_packet = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 		memcpy(priv->multi_data, packet, sizeof(priv->multi_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 	priv->multi_packet = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 	/* Report trackstick */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 	if (alps_get_pkt_id_ss4_v2(packet) == SS4_PACKET_ID_STICK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 		if (!(priv->flags & ALPS_DUALPOINT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 			psmouse_warn(psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 				     "Rejected trackstick packet from non DualPoint device");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 		input_report_rel(dev2, REL_X, SS4_TS_X_V2(packet));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 		input_report_rel(dev2, REL_Y, SS4_TS_Y_V2(packet));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 		input_report_abs(dev2, ABS_PRESSURE, SS4_TS_Z_V2(packet));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 		input_report_key(dev2, BTN_LEFT, f->ts_left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 		input_report_key(dev2, BTN_RIGHT, f->ts_right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 		input_report_key(dev2, BTN_MIDDLE, f->ts_middle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 		input_sync(dev2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 	/* Report touchpad */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 	alps_report_mt_data(psmouse, (f->fingers <= 4) ? f->fingers : 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 	input_mt_report_finger_count(dev, f->fingers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 	input_report_key(dev, BTN_LEFT, f->left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 	input_report_key(dev, BTN_RIGHT, f->right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 	input_report_key(dev, BTN_MIDDLE, f->middle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 	input_report_abs(dev, ABS_PRESSURE, f->pressure);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 	input_sync(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) static bool alps_is_valid_package_ss4_v2(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 	if (psmouse->pktcnt == 4 && ((psmouse->packet[3] & 0x08) != 0x08))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 	if (psmouse->pktcnt == 6 && ((psmouse->packet[5] & 0x10) != 0x0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) static DEFINE_MUTEX(alps_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) static void alps_register_bare_ps2_mouse(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 	struct alps_data *priv =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 		container_of(work, struct alps_data, dev3_register_work.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 	struct psmouse *psmouse = priv->psmouse;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 	struct input_dev *dev3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 	int error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 	mutex_lock(&alps_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 	if (priv->dev3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) 	dev3 = input_allocate_device();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) 	if (!dev3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) 		psmouse_err(psmouse, "failed to allocate secondary device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) 		error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 	snprintf(priv->phys3, sizeof(priv->phys3), "%s/%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 		 psmouse->ps2dev.serio->phys,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 		 (priv->dev2 ? "input2" : "input1"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 	dev3->phys = priv->phys3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 	 * format of input device name is: "protocol vendor name"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 	 * see function psmouse_switch_protocol() in psmouse-base.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) 	dev3->name = "PS/2 ALPS Mouse";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) 	dev3->id.bustype = BUS_I8042;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 	dev3->id.vendor  = 0x0002;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) 	dev3->id.product = PSMOUSE_PS2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) 	dev3->id.version = 0x0000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) 	dev3->dev.parent = &psmouse->ps2dev.serio->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) 	input_set_capability(dev3, EV_REL, REL_X);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) 	input_set_capability(dev3, EV_REL, REL_Y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 	input_set_capability(dev3, EV_KEY, BTN_LEFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) 	input_set_capability(dev3, EV_KEY, BTN_RIGHT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 	input_set_capability(dev3, EV_KEY, BTN_MIDDLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 	__set_bit(INPUT_PROP_POINTER, dev3->propbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) 	error = input_register_device(dev3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) 	if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) 		psmouse_err(psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) 			    "failed to register secondary device: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) 			    error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 		input_free_device(dev3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 	priv->dev3 = dev3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 	 * Save the error code so that we can detect that we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) 	 * already tried to create the device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 		priv->dev3 = ERR_PTR(error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 	mutex_unlock(&alps_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) static void alps_report_bare_ps2_packet(struct psmouse *psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 					unsigned char packet[],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 					bool report_buttons)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 	struct alps_data *priv = psmouse->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 	struct input_dev *dev, *dev2 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 	/* Figure out which device to use to report the bare packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 	if (priv->proto_version == ALPS_PROTO_V2 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) 	    (priv->flags & ALPS_DUALPOINT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) 		/* On V2 devices the DualPoint Stick reports bare packets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) 		dev = priv->dev2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) 		dev2 = psmouse->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) 	} else if (unlikely(IS_ERR_OR_NULL(priv->dev3))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) 		/* Register dev3 mouse if we received PS/2 packet first time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) 		if (!IS_ERR(priv->dev3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) 			psmouse_queue_work(psmouse, &priv->dev3_register_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) 					   0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) 		dev = priv->dev3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) 	if (report_buttons)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) 		alps_report_buttons(dev, dev2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) 				packet[0] & 1, packet[0] & 2, packet[0] & 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) 	psmouse_report_standard_motion(dev, packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 	input_sync(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) static psmouse_ret_t alps_handle_interleaved_ps2(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) 	struct alps_data *priv = psmouse->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) 	if (psmouse->pktcnt < 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) 		return PSMOUSE_GOOD_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) 	if (psmouse->pktcnt == 6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 		 * Start a timer to flush the packet if it ends up last
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) 		 * 6-byte packet in the stream. Timer needs to fire
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) 		 * psmouse core times out itself. 20 ms should be enough
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 		 * to decide if we are getting more data or not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) 		mod_timer(&priv->timer, jiffies + msecs_to_jiffies(20));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) 		return PSMOUSE_GOOD_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) 	del_timer(&priv->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) 	if (psmouse->packet[6] & 0x80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 		 * Highest bit is set - that means we either had
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) 		 * complete ALPS packet and this is start of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 		 * next packet or we got garbage.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) 		if (((psmouse->packet[3] |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) 		      psmouse->packet[4] |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) 		      psmouse->packet[5]) & 0x80) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) 		    (!alps_is_valid_first_byte(priv, psmouse->packet[6]))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) 			psmouse_dbg(psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) 				    "refusing packet %4ph (suspected interleaved ps/2)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) 				    psmouse->packet + 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 			return PSMOUSE_BAD_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 		priv->process_packet(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) 		/* Continue with the next packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) 		psmouse->packet[0] = psmouse->packet[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) 		psmouse->pktcnt = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) 		 * High bit is 0 - that means that we indeed got a PS/2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) 		 * packet in the middle of ALPS packet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) 		 * There is also possibility that we got 6-byte ALPS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) 		 * packet followed  by 3-byte packet from trackpoint. We
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) 		 * can not distinguish between these 2 scenarios but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) 		 * because the latter is unlikely to happen in course of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) 		 * normal operation (user would need to press all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) 		 * buttons on the pad and start moving trackpoint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) 		 * without touching the pad surface) we assume former.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) 		 * Even if we are wrong the wost thing that would happen
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) 		 * the cursor would jump but we should not get protocol
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) 		 * de-synchronization.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) 		alps_report_bare_ps2_packet(psmouse, &psmouse->packet[3],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) 					    false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) 		 * Continue with the standard ALPS protocol handling,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 		 * but make sure we won't process it as an interleaved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) 		 * packet again, which may happen if all buttons are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) 		 * pressed. To avoid this let's reset the 4th bit which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) 		 * is normally 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) 		psmouse->packet[3] = psmouse->packet[6] & 0xf7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) 		psmouse->pktcnt = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) 	return PSMOUSE_GOOD_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) static void alps_flush_packet(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 	struct alps_data *priv = from_timer(priv, t, timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 	struct psmouse *psmouse = priv->psmouse;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 	serio_pause_rx(psmouse->ps2dev.serio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) 	if (psmouse->pktcnt == psmouse->pktsize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) 		 * We did not any more data in reasonable amount of time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) 		 * Validate the last 3 bytes and process as a standard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 		 * ALPS packet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) 		if ((psmouse->packet[3] |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) 		     psmouse->packet[4] |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) 		     psmouse->packet[5]) & 0x80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) 			psmouse_dbg(psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) 				    "refusing packet %3ph (suspected interleaved ps/2)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 				    psmouse->packet + 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 			priv->process_packet(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) 		psmouse->pktcnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) 	serio_continue_rx(psmouse->ps2dev.serio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) static psmouse_ret_t alps_process_byte(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) 	struct alps_data *priv = psmouse->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) 	 * Check if we are dealing with a bare PS/2 packet, presumably from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) 	 * a device connected to the external PS/2 port. Because bare PS/2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) 	 * protocol does not have enough constant bits to self-synchronize
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) 	 * properly we only do this if the device is fully synchronized.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 	 * Can not distinguish V8's first byte from PS/2 packet's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) 	if (priv->proto_version != ALPS_PROTO_V8 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) 	    !psmouse->out_of_sync_cnt &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) 	    (psmouse->packet[0] & 0xc8) == 0x08) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) 		if (psmouse->pktcnt == 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) 			alps_report_bare_ps2_packet(psmouse, psmouse->packet,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) 						    true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) 			return PSMOUSE_FULL_PACKET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) 		return PSMOUSE_GOOD_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) 	/* Check for PS/2 packet stuffed in the middle of ALPS packet. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) 	if ((priv->flags & ALPS_PS2_INTERLEAVED) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) 	    psmouse->pktcnt >= 4 && (psmouse->packet[3] & 0x0f) == 0x0f) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) 		return alps_handle_interleaved_ps2(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) 	if (!alps_is_valid_first_byte(priv, psmouse->packet[0])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) 		psmouse_dbg(psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) 			    "refusing packet[0] = %x (mask0 = %x, byte0 = %x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) 			    psmouse->packet[0], priv->mask0, priv->byte0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) 		return PSMOUSE_BAD_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) 	/* Bytes 2 - pktsize should have 0 in the highest bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) 	if (priv->proto_version < ALPS_PROTO_V5 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) 	    psmouse->pktcnt >= 2 && psmouse->pktcnt <= psmouse->pktsize &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) 	    (psmouse->packet[psmouse->pktcnt - 1] & 0x80)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) 		psmouse_dbg(psmouse, "refusing packet[%i] = %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) 			    psmouse->pktcnt - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) 			    psmouse->packet[psmouse->pktcnt - 1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) 		if (priv->proto_version == ALPS_PROTO_V3_RUSHMORE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) 		    psmouse->pktcnt == psmouse->pktsize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) 			 * Some Dell boxes, such as Latitude E6440 or E7440
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) 			 * with closed lid, quite often smash last byte of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) 			 * otherwise valid packet with 0xff. Given that the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) 			 * next packet is very likely to be valid let's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) 			 * report PSMOUSE_FULL_PACKET but not process data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) 			 * rather than reporting PSMOUSE_BAD_DATA and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) 			 * filling the logs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) 			return PSMOUSE_FULL_PACKET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) 		return PSMOUSE_BAD_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) 	if ((priv->proto_version == ALPS_PROTO_V7 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) 			!alps_is_valid_package_v7(psmouse)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) 	    (priv->proto_version == ALPS_PROTO_V8 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) 			!alps_is_valid_package_ss4_v2(psmouse))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) 		psmouse_dbg(psmouse, "refusing packet[%i] = %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) 			    psmouse->pktcnt - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) 			    psmouse->packet[psmouse->pktcnt - 1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) 		return PSMOUSE_BAD_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) 	if (psmouse->pktcnt == psmouse->pktsize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) 		priv->process_packet(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) 		return PSMOUSE_FULL_PACKET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) 	return PSMOUSE_GOOD_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) static int alps_command_mode_send_nibble(struct psmouse *psmouse, int nibble)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) 	struct ps2dev *ps2dev = &psmouse->ps2dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) 	struct alps_data *priv = psmouse->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) 	int command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) 	unsigned char *param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) 	unsigned char dummy[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) 	BUG_ON(nibble > 0xf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) 	command = priv->nibble_commands[nibble].command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) 	param = (command & 0x0f00) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) 		dummy : (unsigned char *)&priv->nibble_commands[nibble].data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) 	if (ps2_command(ps2dev, param, command))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) static int alps_command_mode_set_addr(struct psmouse *psmouse, int addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) 	struct ps2dev *ps2dev = &psmouse->ps2dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) 	struct alps_data *priv = psmouse->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) 	int i, nibble;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) 	if (ps2_command(ps2dev, NULL, priv->addr_command))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) 	for (i = 12; i >= 0; i -= 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) 		nibble = (addr >> i) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) 		if (alps_command_mode_send_nibble(psmouse, nibble))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) static int __alps_command_mode_read_reg(struct psmouse *psmouse, int addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) 	struct ps2dev *ps2dev = &psmouse->ps2dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) 	unsigned char param[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) 	if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) 	 * The address being read is returned in the first two bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) 	 * of the result. Check that this address matches the expected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) 	 * address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) 	if (addr != ((param[0] << 8) | param[1]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) 	return param[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) static int alps_command_mode_read_reg(struct psmouse *psmouse, int addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) 	if (alps_command_mode_set_addr(psmouse, addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) 	return __alps_command_mode_read_reg(psmouse, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) static int __alps_command_mode_write_reg(struct psmouse *psmouse, u8 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) 	if (alps_command_mode_send_nibble(psmouse, (value >> 4) & 0xf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) 	if (alps_command_mode_send_nibble(psmouse, value & 0xf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) static int alps_command_mode_write_reg(struct psmouse *psmouse, int addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) 				       u8 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) 	if (alps_command_mode_set_addr(psmouse, addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) 	return __alps_command_mode_write_reg(psmouse, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) static int alps_rpt_cmd(struct psmouse *psmouse, int init_command,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) 			int repeated_command, unsigned char *param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) 	struct ps2dev *ps2dev = &psmouse->ps2dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) 	param[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) 	if (init_command && ps2_command(ps2dev, param, init_command))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) 	if (ps2_command(ps2dev,  NULL, repeated_command) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) 	    ps2_command(ps2dev,  NULL, repeated_command) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) 	    ps2_command(ps2dev,  NULL, repeated_command))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) 	param[0] = param[1] = param[2] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) 	if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) 	psmouse_dbg(psmouse, "%2.2X report: %3ph\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) 		    repeated_command, param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) static bool alps_check_valid_firmware_id(unsigned char id[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) 	if (id[0] == 0x73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) 	if (id[0] == 0x88 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) 	    (id[1] == 0x07 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) 	     id[1] == 0x08 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) 	     (id[1] & 0xf0) == 0xb0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) 	     (id[1] & 0xf0) == 0xc0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) static int alps_enter_command_mode(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) 	unsigned char param[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) 	if (alps_rpt_cmd(psmouse, 0, PSMOUSE_CMD_RESET_WRAP, param)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) 		psmouse_err(psmouse, "failed to enter command mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) 	if (!alps_check_valid_firmware_id(param)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) 		psmouse_dbg(psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) 			    "unknown response while entering command mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) static inline int alps_exit_command_mode(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) 	struct ps2dev *ps2dev = &psmouse->ps2dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) 	if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSTREAM))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832)  * For DualPoint devices select the device that should respond to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833)  * subsequent commands. It looks like glidepad is behind stickpointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834)  * I'd thought it would be other way around...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) static int alps_passthrough_mode_v2(struct psmouse *psmouse, bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) 	struct ps2dev *ps2dev = &psmouse->ps2dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) 	int cmd = enable ? PSMOUSE_CMD_SETSCALE21 : PSMOUSE_CMD_SETSCALE11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) 	if (ps2_command(ps2dev, NULL, cmd) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) 	    ps2_command(ps2dev, NULL, cmd) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) 	    ps2_command(ps2dev, NULL, cmd) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) 	    ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) 	/* we may get 3 more bytes, just ignore them */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) 	ps2_drain(ps2dev, 3, 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) static int alps_absolute_mode_v1_v2(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) 	struct ps2dev *ps2dev = &psmouse->ps2dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) 	/* Try ALPS magic knock - 4 disable before enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) 	if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) 	    ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) 	    ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) 	    ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) 	    ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) 	 * Switch mouse to poll (remote) mode so motion data will not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) 	 * get in our way
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) 	return ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETPOLL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) static int alps_monitor_mode_send_word(struct psmouse *psmouse, u16 word)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) 	int i, nibble;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) 	 * b0-b11 are valid bits, send sequence is inverse.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) 	 * e.g. when word = 0x0123, nibble send sequence is 3, 2, 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) 	for (i = 0; i <= 8; i += 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) 		nibble = (word >> i) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) 		if (alps_command_mode_send_nibble(psmouse, nibble))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) static int alps_monitor_mode_write_reg(struct psmouse *psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) 				       u16 addr, u16 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) 	struct ps2dev *ps2dev = &psmouse->ps2dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) 	/* 0x0A0 is the command to write the word */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) 	if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) 	    alps_monitor_mode_send_word(psmouse, 0x0A0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) 	    alps_monitor_mode_send_word(psmouse, addr) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) 	    alps_monitor_mode_send_word(psmouse, value) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) 	    ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) static int alps_monitor_mode(struct psmouse *psmouse, bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) 	struct ps2dev *ps2dev = &psmouse->ps2dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) 	if (enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) 		/* EC E9 F5 F5 E7 E6 E7 E9 to enter monitor mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) 		if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_WRAP) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) 		    ps2_command(ps2dev, NULL, PSMOUSE_CMD_GETINFO) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) 		    ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) 		    ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) 		    ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) 		    ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) 		    ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) 		    ps2_command(ps2dev, NULL, PSMOUSE_CMD_GETINFO))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) 		/* EC to exit monitor mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) 		if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_WRAP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) static int alps_absolute_mode_v6(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) 	u16 reg_val = 0x181;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) 	/* enter monitor mode, to write the register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) 	if (alps_monitor_mode(psmouse, true))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) 	ret = alps_monitor_mode_write_reg(psmouse, 0x000, reg_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) 	if (alps_monitor_mode(psmouse, false))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) 		ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) static int alps_get_status(struct psmouse *psmouse, char *param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) 	/* Get status: 0xF5 0xF5 0xF5 0xE9 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) 	if (alps_rpt_cmd(psmouse, 0, PSMOUSE_CMD_DISABLE, param))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956)  * Turn touchpad tapping on or off. The sequences are:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957)  * 0xE9 0xF5 0xF5 0xF3 0x0A to enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958)  * 0xE9 0xF5 0xF5 0xE8 0x00 to disable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959)  * My guess that 0xE9 (GetInfo) is here as a sync point.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960)  * For models that also have stickpointer (DualPoints) its tapping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961)  * is controlled separately (0xE6 0xE6 0xE6 0xF3 0x14|0x0A) but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962)  * we don't fiddle with it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) static int alps_tap_mode(struct psmouse *psmouse, int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) 	struct ps2dev *ps2dev = &psmouse->ps2dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) 	int cmd = enable ? PSMOUSE_CMD_SETRATE : PSMOUSE_CMD_SETRES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) 	unsigned char tap_arg = enable ? 0x0A : 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) 	unsigned char param[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) 	if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) 	    ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) 	    ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) 	    ps2_command(ps2dev, &tap_arg, cmd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) 	if (alps_get_status(psmouse, param))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984)  * alps_poll() - poll the touchpad for current motion packet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985)  * Used in resync.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) static int alps_poll(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) 	struct alps_data *priv = psmouse->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) 	unsigned char buf[sizeof(psmouse->packet)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) 	bool poll_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) 	if (priv->flags & ALPS_PASS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) 		alps_passthrough_mode_v2(psmouse, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) 	poll_failed = ps2_command(&psmouse->ps2dev, buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) 				  PSMOUSE_CMD_POLL | (psmouse->pktsize << 8)) < 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) 	if (priv->flags & ALPS_PASS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) 		alps_passthrough_mode_v2(psmouse, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) 	if (poll_failed || (buf[0] & priv->mask0) != priv->byte0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) 	if ((psmouse->badbyte & 0xc8) == 0x08) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007)  * Poll the track stick ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) 		if (ps2_command(&psmouse->ps2dev, buf, PSMOUSE_CMD_POLL | (3 << 8)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) 	memcpy(psmouse->packet, buf, sizeof(buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) static int alps_hw_init_v1_v2(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) 	struct alps_data *priv = psmouse->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) 	if ((priv->flags & ALPS_PASS) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) 	    alps_passthrough_mode_v2(psmouse, true)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) 	if (alps_tap_mode(psmouse, true)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) 		psmouse_warn(psmouse, "Failed to enable hardware tapping\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) 	if (alps_absolute_mode_v1_v2(psmouse)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) 		psmouse_err(psmouse, "Failed to enable absolute mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) 	if ((priv->flags & ALPS_PASS) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) 	    alps_passthrough_mode_v2(psmouse, false)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) 	/* ALPS needs stream mode, otherwise it won't report any data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) 	if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSTREAM)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) 		psmouse_err(psmouse, "Failed to enable stream mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) /* Must be in passthrough mode when calling this function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) static int alps_trackstick_enter_extended_mode_v3_v6(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) 	unsigned char param[2] = {0xC8, 0x14};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) 	if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) 	    ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) 	    ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) 	    ps2_command(&psmouse->ps2dev, &param[0], PSMOUSE_CMD_SETRATE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) 	    ps2_command(&psmouse->ps2dev, &param[1], PSMOUSE_CMD_SETRATE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) static int alps_hw_init_v6(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) 	/* Enter passthrough mode to let trackpoint enter 6byte raw mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) 	if (alps_passthrough_mode_v2(psmouse, true))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) 	ret = alps_trackstick_enter_extended_mode_v3_v6(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) 	if (alps_passthrough_mode_v2(psmouse, false))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) 	if (alps_absolute_mode_v6(psmouse)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) 		psmouse_err(psmouse, "Failed to enable absolute mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090)  * Enable or disable passthrough mode to the trackstick.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) static int alps_passthrough_mode_v3(struct psmouse *psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) 				    int reg_base, bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) 	int reg_val, ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) 	if (alps_enter_command_mode(psmouse))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) 	reg_val = alps_command_mode_read_reg(psmouse, reg_base + 0x0008);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) 	if (reg_val == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) 	if (enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) 		reg_val |= 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) 		reg_val &= ~0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) 	ret = __alps_command_mode_write_reg(psmouse, reg_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) 	if (alps_exit_command_mode(psmouse))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) 		ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) /* Must be in command mode when calling this function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) static int alps_absolute_mode_v3(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) 	int reg_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) 	reg_val = alps_command_mode_read_reg(psmouse, 0x0004);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) 	if (reg_val == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) 	reg_val |= 0x06;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) 	if (__alps_command_mode_write_reg(psmouse, reg_val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) static int alps_probe_trackstick_v3_v7(struct psmouse *psmouse, int reg_base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) 	int ret = -EIO, reg_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) 	if (alps_enter_command_mode(psmouse))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) 	reg_val = alps_command_mode_read_reg(psmouse, reg_base + 0x08);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) 	if (reg_val == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) 	/* bit 7: trackstick is present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) 	ret = reg_val & 0x80 ? 0 : -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) 	alps_exit_command_mode(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) static int alps_setup_trackstick_v3(struct psmouse *psmouse, int reg_base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) 	int reg_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) 	unsigned char param[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) 	 * We need to configure trackstick to report data for touchpad in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) 	 * extended format. And also we need to tell touchpad to expect data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) 	 * from trackstick in extended format. Without this configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) 	 * trackstick packets sent from touchpad are in basic format which is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) 	 * different from what we expect.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) 	if (alps_passthrough_mode_v3(psmouse, reg_base, true))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) 	 * E7 report for the trackstick
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) 	 * There have been reports of failures to seem to trace back
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) 	 * to the above trackstick check failing. When these occur
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) 	 * this E7 report fails, so when that happens we continue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) 	 * with the assumption that there isn't a trackstick after
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) 	 * all.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) 	if (alps_rpt_cmd(psmouse, 0, PSMOUSE_CMD_SETSCALE21, param)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) 		psmouse_warn(psmouse, "Failed to initialize trackstick (E7 report failed)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) 		ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) 		psmouse_dbg(psmouse, "trackstick E7 report: %3ph\n", param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) 		if (alps_trackstick_enter_extended_mode_v3_v6(psmouse)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) 			psmouse_err(psmouse, "Failed to enter into trackstick extended mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) 			ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) 	if (alps_passthrough_mode_v3(psmouse, reg_base, false))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) 	if (alps_enter_command_mode(psmouse))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) 	reg_val = alps_command_mode_read_reg(psmouse, reg_base + 0x08);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) 	if (reg_val == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) 		ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) 		 * Tell touchpad that trackstick is now in extended mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) 		 * If bit 1 isn't set the packet format is different.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) 		reg_val |= BIT(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) 		if (__alps_command_mode_write_reg(psmouse, reg_val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) 			ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) 	if (alps_exit_command_mode(psmouse))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) static int alps_hw_init_v3(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) 	struct alps_data *priv = psmouse->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) 	struct ps2dev *ps2dev = &psmouse->ps2dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) 	int reg_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) 	unsigned char param[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) 	if ((priv->flags & ALPS_DUALPOINT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) 	    alps_setup_trackstick_v3(psmouse, ALPS_REG_BASE_PINNACLE) == -EIO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) 	if (alps_enter_command_mode(psmouse) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) 	    alps_absolute_mode_v3(psmouse)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) 		psmouse_err(psmouse, "Failed to enter absolute mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) 	reg_val = alps_command_mode_read_reg(psmouse, 0x0006);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) 	if (reg_val == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) 	if (__alps_command_mode_write_reg(psmouse, reg_val | 0x01))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) 	reg_val = alps_command_mode_read_reg(psmouse, 0x0007);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) 	if (reg_val == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) 	if (__alps_command_mode_write_reg(psmouse, reg_val | 0x01))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) 	if (alps_command_mode_read_reg(psmouse, 0x0144) == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) 	if (__alps_command_mode_write_reg(psmouse, 0x04))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) 	if (alps_command_mode_read_reg(psmouse, 0x0159) == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) 	if (__alps_command_mode_write_reg(psmouse, 0x03))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) 	if (alps_command_mode_read_reg(psmouse, 0x0163) == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) 	if (alps_command_mode_write_reg(psmouse, 0x0163, 0x03))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) 	if (alps_command_mode_read_reg(psmouse, 0x0162) == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) 	if (alps_command_mode_write_reg(psmouse, 0x0162, 0x04))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) 	alps_exit_command_mode(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) 	/* Set rate and enable data reporting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) 	param[0] = 0x64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) 	if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) 	    ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) 		psmouse_err(psmouse, "Failed to enable data reporting\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) 	 * Leaving the touchpad in command mode will essentially render
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) 	 * it unusable until the machine reboots, so exit it here just
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) 	 * to be safe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) 	alps_exit_command_mode(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) static int alps_get_v3_v7_resolution(struct psmouse *psmouse, int reg_pitch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) 	int reg, x_pitch, y_pitch, x_electrode, y_electrode, x_phys, y_phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) 	struct alps_data *priv = psmouse->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) 	reg = alps_command_mode_read_reg(psmouse, reg_pitch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) 	if (reg < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) 		return reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) 	x_pitch = (char)(reg << 4) >> 4; /* sign extend lower 4 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) 	x_pitch = 50 + 2 * x_pitch; /* In 0.1 mm units */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) 	y_pitch = (char)reg >> 4; /* sign extend upper 4 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) 	y_pitch = 36 + 2 * y_pitch; /* In 0.1 mm units */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) 	reg = alps_command_mode_read_reg(psmouse, reg_pitch + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) 	if (reg < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) 		return reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) 	x_electrode = (char)(reg << 4) >> 4; /* sign extend lower 4 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) 	x_electrode = 17 + x_electrode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) 	y_electrode = (char)reg >> 4; /* sign extend upper 4 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) 	y_electrode = 13 + y_electrode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) 	x_phys = x_pitch * (x_electrode - 1); /* In 0.1 mm units */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) 	y_phys = y_pitch * (y_electrode - 1); /* In 0.1 mm units */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) 	priv->x_res = priv->x_max * 10 / x_phys; /* units / mm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) 	priv->y_res = priv->y_max * 10 / y_phys; /* units / mm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) 	psmouse_dbg(psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) 		    "pitch %dx%d num-electrodes %dx%d physical size %dx%d mm res %dx%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) 		    x_pitch, y_pitch, x_electrode, y_electrode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) 		    x_phys / 10, y_phys / 10, priv->x_res, priv->y_res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) static int alps_hw_init_rushmore_v3(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) 	struct alps_data *priv = psmouse->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) 	struct ps2dev *ps2dev = &psmouse->ps2dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) 	int reg_val, ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) 	if (priv->flags & ALPS_DUALPOINT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) 		reg_val = alps_setup_trackstick_v3(psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) 						   ALPS_REG_BASE_RUSHMORE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) 		if (reg_val == -EIO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) 	if (alps_enter_command_mode(psmouse) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) 	    alps_command_mode_read_reg(psmouse, 0xc2d9) == -1 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) 	    alps_command_mode_write_reg(psmouse, 0xc2cb, 0x00))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) 	if (alps_get_v3_v7_resolution(psmouse, 0xc2da))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) 	reg_val = alps_command_mode_read_reg(psmouse, 0xc2c6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) 	if (reg_val == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) 	if (__alps_command_mode_write_reg(psmouse, reg_val & 0xfd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) 	if (alps_command_mode_write_reg(psmouse, 0xc2c9, 0x64))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) 	/* enter absolute mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) 	reg_val = alps_command_mode_read_reg(psmouse, 0xc2c4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) 	if (reg_val == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) 	if (__alps_command_mode_write_reg(psmouse, reg_val | 0x02))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) 	alps_exit_command_mode(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) 	return ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) 	alps_exit_command_mode(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) /* Must be in command mode when calling this function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) static int alps_absolute_mode_v4(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) 	int reg_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) 	reg_val = alps_command_mode_read_reg(psmouse, 0x0004);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) 	if (reg_val == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) 	reg_val |= 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) 	if (__alps_command_mode_write_reg(psmouse, reg_val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) static int alps_hw_init_v4(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) 	struct ps2dev *ps2dev = &psmouse->ps2dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) 	unsigned char param[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) 	if (alps_enter_command_mode(psmouse))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) 	if (alps_absolute_mode_v4(psmouse)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) 		psmouse_err(psmouse, "Failed to enter absolute mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) 	if (alps_command_mode_write_reg(psmouse, 0x0007, 0x8c))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) 	if (alps_command_mode_write_reg(psmouse, 0x0149, 0x03))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) 	if (alps_command_mode_write_reg(psmouse, 0x0160, 0x03))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) 	if (alps_command_mode_write_reg(psmouse, 0x017f, 0x15))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) 	if (alps_command_mode_write_reg(psmouse, 0x0151, 0x01))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) 	if (alps_command_mode_write_reg(psmouse, 0x0168, 0x03))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) 	if (alps_command_mode_write_reg(psmouse, 0x014a, 0x03))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) 	if (alps_command_mode_write_reg(psmouse, 0x0161, 0x03))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) 	alps_exit_command_mode(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) 	 * This sequence changes the output from a 9-byte to an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) 	 * 8-byte format. All the same data seems to be present,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) 	 * just in a more compact format.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) 	param[0] = 0xc8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) 	param[1] = 0x64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) 	param[2] = 0x50;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) 	if (ps2_command(ps2dev, &param[0], PSMOUSE_CMD_SETRATE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) 	    ps2_command(ps2dev, &param[1], PSMOUSE_CMD_SETRATE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) 	    ps2_command(ps2dev, &param[2], PSMOUSE_CMD_SETRATE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) 	    ps2_command(ps2dev, param, PSMOUSE_CMD_GETID))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) 	/* Set rate and enable data reporting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) 	param[0] = 0x64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) 	if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) 	    ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) 		psmouse_err(psmouse, "Failed to enable data reporting\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) 	 * Leaving the touchpad in command mode will essentially render
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) 	 * it unusable until the machine reboots, so exit it here just
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) 	 * to be safe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) 	alps_exit_command_mode(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) static int alps_get_otp_values_ss4_v2(struct psmouse *psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) 				      unsigned char index, unsigned char otp[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) 	struct ps2dev *ps2dev = &psmouse->ps2dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) 	switch (index) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) 	case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) 		if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSTREAM)  ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) 		    ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSTREAM)  ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) 		    ps2_command(ps2dev, otp, PSMOUSE_CMD_GETINFO))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) 	case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) 		if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETPOLL)  ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) 		    ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETPOLL)  ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) 		    ps2_command(ps2dev, otp, PSMOUSE_CMD_GETINFO))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) static int alps_update_device_area_ss4_v2(unsigned char otp[][4],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) 					  struct alps_data *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) 	int num_x_electrode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) 	int num_y_electrode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) 	int x_pitch, y_pitch, x_phys, y_phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) 	if (IS_SS4PLUS_DEV(priv->dev_id)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) 		num_x_electrode =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) 			SS4PLUS_NUMSENSOR_XOFFSET + (otp[0][2] & 0x0F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) 		num_y_electrode =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) 			SS4PLUS_NUMSENSOR_YOFFSET + ((otp[0][2] >> 4) & 0x0F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) 		priv->x_max =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) 			(num_x_electrode - 1) * SS4PLUS_COUNT_PER_ELECTRODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) 		priv->y_max =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) 			(num_y_electrode - 1) * SS4PLUS_COUNT_PER_ELECTRODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) 		x_pitch = (otp[0][1] & 0x0F) + SS4PLUS_MIN_PITCH_MM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) 		y_pitch = ((otp[0][1] >> 4) & 0x0F) + SS4PLUS_MIN_PITCH_MM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) 		num_x_electrode =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) 			SS4_NUMSENSOR_XOFFSET + (otp[1][0] & 0x0F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) 		num_y_electrode =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) 			SS4_NUMSENSOR_YOFFSET + ((otp[1][0] >> 4) & 0x0F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) 		priv->x_max =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) 			(num_x_electrode - 1) * SS4_COUNT_PER_ELECTRODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) 		priv->y_max =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) 			(num_y_electrode - 1) * SS4_COUNT_PER_ELECTRODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) 		x_pitch = ((otp[1][2] >> 2) & 0x07) + SS4_MIN_PITCH_MM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) 		y_pitch = ((otp[1][2] >> 5) & 0x07) + SS4_MIN_PITCH_MM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) 	x_phys = x_pitch * (num_x_electrode - 1); /* In 0.1 mm units */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) 	y_phys = y_pitch * (num_y_electrode - 1); /* In 0.1 mm units */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) 	priv->x_res = priv->x_max * 10 / x_phys; /* units / mm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) 	priv->y_res = priv->y_max * 10 / y_phys; /* units / mm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) static int alps_update_btn_info_ss4_v2(unsigned char otp[][4],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) 				       struct alps_data *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) 	unsigned char is_btnless;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) 	if (IS_SS4PLUS_DEV(priv->dev_id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) 		is_btnless = (otp[1][0] >> 1) & 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) 		is_btnless = (otp[1][1] >> 3) & 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) 	if (is_btnless)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) 		priv->flags |= ALPS_BUTTONPAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) static int alps_update_dual_info_ss4_v2(unsigned char otp[][4],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) 					struct alps_data *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) 					struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) 	bool is_dual = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) 	int reg_val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) 	struct ps2dev *ps2dev = &psmouse->ps2dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) 	if (IS_SS4PLUS_DEV(priv->dev_id)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) 		is_dual = (otp[0][0] >> 4) & 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) 		if (!is_dual) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) 			/* For support TrackStick of Thinkpad L/E series */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) 			if (alps_exit_command_mode(psmouse) == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) 				alps_enter_command_mode(psmouse) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) 				reg_val = alps_command_mode_read_reg(psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) 									0xD7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) 			alps_exit_command_mode(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) 			ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) 			if (reg_val == 0x0C || reg_val == 0x1D)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) 				is_dual = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) 	if (is_dual)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) 		priv->flags |= ALPS_DUALPOINT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) 					ALPS_DUALPOINT_WITH_PRESSURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) static int alps_set_defaults_ss4_v2(struct psmouse *psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) 				    struct alps_data *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) 	unsigned char otp[2][4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) 	memset(otp, 0, sizeof(otp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) 	if (alps_get_otp_values_ss4_v2(psmouse, 1, &otp[1][0]) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) 	    alps_get_otp_values_ss4_v2(psmouse, 0, &otp[0][0]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) 	alps_update_device_area_ss4_v2(otp, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) 	alps_update_btn_info_ss4_v2(otp, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) 	alps_update_dual_info_ss4_v2(otp, priv, psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) static int alps_dolphin_get_device_area(struct psmouse *psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) 					struct alps_data *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) 	struct ps2dev *ps2dev = &psmouse->ps2dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) 	unsigned char param[4] = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) 	int num_x_electrode, num_y_electrode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) 	if (alps_enter_command_mode(psmouse))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) 	param[0] = 0x0a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) 	if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_WRAP) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) 	    ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETPOLL) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) 	    ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETPOLL) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) 	    ps2_command(ps2dev, &param[0], PSMOUSE_CMD_SETRATE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) 	    ps2_command(ps2dev, &param[0], PSMOUSE_CMD_SETRATE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) 	if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) 	 * Dolphin's sensor line number is not fixed. It can be calculated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) 	 * by adding the device's register value with DOLPHIN_PROFILE_X/YOFFSET.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) 	 * Further more, we can get device's x_max and y_max by multiplying
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) 	 * sensor line number with DOLPHIN_COUNT_PER_ELECTRODE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) 	 * e.g. When we get register's sensor_x = 11 & sensor_y = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) 	 *	real sensor line number X = 11 + 8 = 19, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) 	 *	real sensor line number Y = 8 + 1 = 9.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) 	 *	So, x_max = (19 - 1) * 64 = 1152, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) 	 *	    y_max = (9 - 1) * 64 = 512.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) 	num_x_electrode = DOLPHIN_PROFILE_XOFFSET + (param[2] & 0x0F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) 	num_y_electrode = DOLPHIN_PROFILE_YOFFSET + ((param[2] >> 4) & 0x0F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) 	priv->x_bits = num_x_electrode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) 	priv->y_bits = num_y_electrode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) 	priv->x_max = (num_x_electrode - 1) * DOLPHIN_COUNT_PER_ELECTRODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) 	priv->y_max = (num_y_electrode - 1) * DOLPHIN_COUNT_PER_ELECTRODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) 	if (alps_exit_command_mode(psmouse))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) static int alps_hw_init_dolphin_v1(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) 	struct ps2dev *ps2dev = &psmouse->ps2dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) 	unsigned char param[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) 	/* This is dolphin "v1" as empirically defined by florin9doi */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) 	param[0] = 0x64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) 	param[1] = 0x28;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) 	if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSTREAM) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) 	    ps2_command(ps2dev, &param[0], PSMOUSE_CMD_SETRATE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) 	    ps2_command(ps2dev, &param[1], PSMOUSE_CMD_SETRATE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) static int alps_hw_init_v7(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) 	struct ps2dev *ps2dev = &psmouse->ps2dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) 	int reg_val, ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) 	if (alps_enter_command_mode(psmouse) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) 	    alps_command_mode_read_reg(psmouse, 0xc2d9) == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) 	if (alps_get_v3_v7_resolution(psmouse, 0xc397))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) 	if (alps_command_mode_write_reg(psmouse, 0xc2c9, 0x64))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) 	reg_val = alps_command_mode_read_reg(psmouse, 0xc2c4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) 	if (reg_val == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) 	if (__alps_command_mode_write_reg(psmouse, reg_val | 0x02))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) 	alps_exit_command_mode(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) 	return ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) 	alps_exit_command_mode(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) static int alps_hw_init_ss4_v2(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) 	struct ps2dev *ps2dev = &psmouse->ps2dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) 	char param[2] = {0x64, 0x28};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) 	int ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) 	/* enter absolute mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) 	if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSTREAM) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) 	    ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSTREAM) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) 	    ps2_command(ps2dev, &param[0], PSMOUSE_CMD_SETRATE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) 	    ps2_command(ps2dev, &param[1], PSMOUSE_CMD_SETRATE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) 	/* T.B.D. Decread noise packet number, delete in the future */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) 	if (alps_exit_command_mode(psmouse) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) 	    alps_enter_command_mode(psmouse) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) 	    alps_command_mode_write_reg(psmouse, 0x001D, 0x20)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) 	alps_exit_command_mode(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) 	return ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) 	alps_exit_command_mode(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) static int alps_set_protocol(struct psmouse *psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) 			     struct alps_data *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) 			     const struct alps_protocol_info *protocol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) 	psmouse->private = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) 	timer_setup(&priv->timer, alps_flush_packet, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) 	priv->proto_version = protocol->version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) 	priv->byte0 = protocol->byte0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) 	priv->mask0 = protocol->mask0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) 	priv->flags = protocol->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) 	priv->x_max = 2000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) 	priv->y_max = 1400;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) 	priv->x_bits = 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) 	priv->y_bits = 11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) 	switch (priv->proto_version) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) 	case ALPS_PROTO_V1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) 	case ALPS_PROTO_V2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) 		priv->hw_init = alps_hw_init_v1_v2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) 		priv->process_packet = alps_process_packet_v1_v2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) 		priv->set_abs_params = alps_set_abs_params_st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) 		priv->x_max = 1023;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) 		priv->y_max = 767;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) 		if (dmi_check_system(alps_dmi_has_separate_stick_buttons))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) 			priv->flags |= ALPS_STICK_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) 	case ALPS_PROTO_V3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) 		priv->hw_init = alps_hw_init_v3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) 		priv->process_packet = alps_process_packet_v3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) 		priv->set_abs_params = alps_set_abs_params_semi_mt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) 		priv->decode_fields = alps_decode_pinnacle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) 		priv->nibble_commands = alps_v3_nibble_commands;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) 		priv->addr_command = PSMOUSE_CMD_RESET_WRAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) 		if (alps_probe_trackstick_v3_v7(psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) 						ALPS_REG_BASE_PINNACLE) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) 			priv->flags &= ~ALPS_DUALPOINT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) 	case ALPS_PROTO_V3_RUSHMORE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) 		priv->hw_init = alps_hw_init_rushmore_v3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) 		priv->process_packet = alps_process_packet_v3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) 		priv->set_abs_params = alps_set_abs_params_semi_mt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) 		priv->decode_fields = alps_decode_rushmore;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) 		priv->nibble_commands = alps_v3_nibble_commands;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) 		priv->addr_command = PSMOUSE_CMD_RESET_WRAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) 		priv->x_bits = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) 		priv->y_bits = 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) 		if (alps_probe_trackstick_v3_v7(psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) 						ALPS_REG_BASE_RUSHMORE) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) 			priv->flags &= ~ALPS_DUALPOINT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) 	case ALPS_PROTO_V4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) 		priv->hw_init = alps_hw_init_v4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) 		priv->process_packet = alps_process_packet_v4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) 		priv->set_abs_params = alps_set_abs_params_semi_mt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) 		priv->nibble_commands = alps_v4_nibble_commands;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) 		priv->addr_command = PSMOUSE_CMD_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) 	case ALPS_PROTO_V5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) 		priv->hw_init = alps_hw_init_dolphin_v1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) 		priv->process_packet = alps_process_touchpad_packet_v3_v5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) 		priv->decode_fields = alps_decode_dolphin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) 		priv->set_abs_params = alps_set_abs_params_semi_mt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) 		priv->nibble_commands = alps_v3_nibble_commands;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) 		priv->addr_command = PSMOUSE_CMD_RESET_WRAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) 		priv->x_bits = 23;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) 		priv->y_bits = 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) 		if (alps_dolphin_get_device_area(psmouse, priv))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) 			return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) 	case ALPS_PROTO_V6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) 		priv->hw_init = alps_hw_init_v6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) 		priv->process_packet = alps_process_packet_v6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) 		priv->set_abs_params = alps_set_abs_params_st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) 		priv->nibble_commands = alps_v6_nibble_commands;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) 		priv->x_max = 2047;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) 		priv->y_max = 1535;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) 	case ALPS_PROTO_V7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) 		priv->hw_init = alps_hw_init_v7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) 		priv->process_packet = alps_process_packet_v7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) 		priv->decode_fields = alps_decode_packet_v7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) 		priv->set_abs_params = alps_set_abs_params_v7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) 		priv->nibble_commands = alps_v3_nibble_commands;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) 		priv->addr_command = PSMOUSE_CMD_RESET_WRAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) 		priv->x_max = 0xfff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) 		priv->y_max = 0x7ff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) 		if (priv->fw_ver[1] != 0xba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) 			priv->flags |= ALPS_BUTTONPAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) 		if (alps_probe_trackstick_v3_v7(psmouse, ALPS_REG_BASE_V7) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) 			priv->flags &= ~ALPS_DUALPOINT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) 	case ALPS_PROTO_V8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) 		priv->hw_init = alps_hw_init_ss4_v2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) 		priv->process_packet = alps_process_packet_ss4_v2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) 		priv->decode_fields = alps_decode_ss4_v2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) 		priv->set_abs_params = alps_set_abs_params_ss4_v2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) 		priv->nibble_commands = alps_v3_nibble_commands;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) 		priv->addr_command = PSMOUSE_CMD_RESET_WRAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) 		if (alps_set_defaults_ss4_v2(psmouse, priv))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) 			return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) static const struct alps_protocol_info *alps_match_table(unsigned char *e7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) 							 unsigned char *ec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) 	const struct alps_model_info *model;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) 	for (i = 0; i < ARRAY_SIZE(alps_model_data); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) 		model = &alps_model_data[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) 		if (!memcmp(e7, model->signature, sizeof(model->signature)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) 			return &model->protocol_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) static bool alps_is_cs19_trackpoint(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) 	u8 param[2] = { 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) 	if (ps2_command(&psmouse->ps2dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) 			param, MAKE_PS2_CMD(0, 2, TP_READ_ID)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) 	 * param[0] contains the trackpoint device variant_id while
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) 	 * param[1] contains the firmware_id. So far all alps
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) 	 * trackpoint-only devices have their variant_ids equal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) 	 * TP_VARIANT_ALPS and their firmware_ids are in 0x20~0x2f range.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) 	return param[0] == TP_VARIANT_ALPS && ((param[1] & 0xf0) == 0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) static int alps_identify(struct psmouse *psmouse, struct alps_data *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) 	const struct alps_protocol_info *protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) 	unsigned char e6[4], e7[4], ec[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) 	 * First try "E6 report".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) 	 * ALPS should return 0,0,10 or 0,0,100 if no buttons are pressed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) 	 * The bits 0-2 of the first byte will be 1s if some buttons are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) 	 * pressed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) 	if (alps_rpt_cmd(psmouse, PSMOUSE_CMD_SETRES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) 			 PSMOUSE_CMD_SETSCALE11, e6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) 	if ((e6[0] & 0xf8) != 0 || e6[1] != 0 || (e6[2] != 10 && e6[2] != 100))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) 	 * Now get the "E7" and "EC" reports.  These will uniquely identify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) 	 * most ALPS touchpads.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) 	if (alps_rpt_cmd(psmouse, PSMOUSE_CMD_SETRES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) 			 PSMOUSE_CMD_SETSCALE21, e7) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) 	    alps_rpt_cmd(psmouse, PSMOUSE_CMD_SETRES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) 			 PSMOUSE_CMD_RESET_WRAP, ec) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) 	    alps_exit_command_mode(psmouse))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) 	protocol = alps_match_table(e7, ec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) 	if (!protocol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) 		if (e7[0] == 0x73 && e7[1] == 0x02 && e7[2] == 0x64 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) 			   ec[2] == 0x8a) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) 			protocol = &alps_v4_protocol_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) 		} else if (e7[0] == 0x73 && e7[1] == 0x03 && e7[2] == 0x50 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) 			   ec[0] == 0x73 && (ec[1] == 0x01 || ec[1] == 0x02)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) 			protocol = &alps_v5_protocol_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) 		} else if (ec[0] == 0x88 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) 			   ((ec[1] & 0xf0) == 0xb0 || (ec[1] & 0xf0) == 0xc0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) 			protocol = &alps_v7_protocol_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) 		} else if (ec[0] == 0x88 && ec[1] == 0x08) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) 			protocol = &alps_v3_rushmore_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) 		} else if (ec[0] == 0x88 && ec[1] == 0x07 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) 			   ec[2] >= 0x90 && ec[2] <= 0x9d) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) 			protocol = &alps_v3_protocol_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) 		} else if (e7[0] == 0x73 && e7[1] == 0x03 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) 			   (e7[2] == 0x14 || e7[2] == 0x28)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) 			protocol = &alps_v8_protocol_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) 		} else if (e7[0] == 0x73 && e7[1] == 0x03 && e7[2] == 0xc8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) 			protocol = &alps_v9_protocol_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) 			psmouse_warn(psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) 				     "Unsupported ALPS V9 touchpad: E7=%3ph, EC=%3ph\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) 				     e7, ec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) 			psmouse_dbg(psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) 				    "Likely not an ALPS touchpad: E7=%3ph, EC=%3ph\n", e7, ec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) 	if (priv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) 		/* Save Device ID and Firmware version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) 		memcpy(priv->dev_id, e7, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) 		memcpy(priv->fw_ver, ec, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) 		error = alps_set_protocol(psmouse, priv, protocol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) 			return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) static int alps_reconnect(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) 	struct alps_data *priv = psmouse->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) 	psmouse_reset(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) 	if (alps_identify(psmouse, priv) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) 	return priv->hw_init(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) static void alps_disconnect(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) 	struct alps_data *priv = psmouse->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) 	psmouse_reset(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) 	del_timer_sync(&priv->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) 	if (priv->dev2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) 		input_unregister_device(priv->dev2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) 	if (!IS_ERR_OR_NULL(priv->dev3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) 		input_unregister_device(priv->dev3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) 	kfree(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) static void alps_set_abs_params_st(struct alps_data *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) 				   struct input_dev *dev1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) 	input_set_abs_params(dev1, ABS_X, 0, priv->x_max, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) 	input_set_abs_params(dev1, ABS_Y, 0, priv->y_max, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) 	input_set_abs_params(dev1, ABS_PRESSURE, 0, 127, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) static void alps_set_abs_params_mt_common(struct alps_data *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) 					  struct input_dev *dev1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) 	input_set_abs_params(dev1, ABS_MT_POSITION_X, 0, priv->x_max, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) 	input_set_abs_params(dev1, ABS_MT_POSITION_Y, 0, priv->y_max, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) 	input_abs_set_res(dev1, ABS_MT_POSITION_X, priv->x_res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) 	input_abs_set_res(dev1, ABS_MT_POSITION_Y, priv->y_res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) 	set_bit(BTN_TOOL_TRIPLETAP, dev1->keybit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) 	set_bit(BTN_TOOL_QUADTAP, dev1->keybit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) static void alps_set_abs_params_semi_mt(struct alps_data *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) 					struct input_dev *dev1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) 	alps_set_abs_params_mt_common(priv, dev1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) 	input_set_abs_params(dev1, ABS_PRESSURE, 0, 127, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) 	input_mt_init_slots(dev1, MAX_TOUCHES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) 			    INPUT_MT_POINTER | INPUT_MT_DROP_UNUSED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) 				INPUT_MT_SEMI_MT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) static void alps_set_abs_params_v7(struct alps_data *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) 				   struct input_dev *dev1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) 	alps_set_abs_params_mt_common(priv, dev1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) 	set_bit(BTN_TOOL_QUINTTAP, dev1->keybit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) 	input_mt_init_slots(dev1, MAX_TOUCHES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) 			    INPUT_MT_POINTER | INPUT_MT_DROP_UNUSED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) 				INPUT_MT_TRACK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) 	set_bit(BTN_TOOL_QUINTTAP, dev1->keybit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) static void alps_set_abs_params_ss4_v2(struct alps_data *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) 				       struct input_dev *dev1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) 	alps_set_abs_params_mt_common(priv, dev1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) 	input_set_abs_params(dev1, ABS_PRESSURE, 0, 127, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) 	set_bit(BTN_TOOL_QUINTTAP, dev1->keybit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) 	input_mt_init_slots(dev1, MAX_TOUCHES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) 			    INPUT_MT_POINTER | INPUT_MT_DROP_UNUSED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) 				INPUT_MT_TRACK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) int alps_init(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) 	struct alps_data *priv = psmouse->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) 	struct input_dev *dev1 = psmouse->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) 	error = priv->hw_init(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) 		goto init_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) 	 * Undo part of setup done for us by psmouse core since touchpad
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) 	 * is not a relative device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) 	__clear_bit(EV_REL, dev1->evbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) 	__clear_bit(REL_X, dev1->relbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) 	__clear_bit(REL_Y, dev1->relbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) 	 * Now set up our capabilities.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) 	dev1->evbit[BIT_WORD(EV_KEY)] |= BIT_MASK(EV_KEY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) 	dev1->keybit[BIT_WORD(BTN_TOUCH)] |= BIT_MASK(BTN_TOUCH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) 	dev1->keybit[BIT_WORD(BTN_TOOL_FINGER)] |= BIT_MASK(BTN_TOOL_FINGER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) 	dev1->keybit[BIT_WORD(BTN_LEFT)] |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) 		BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) 	dev1->evbit[BIT_WORD(EV_ABS)] |= BIT_MASK(EV_ABS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) 	priv->set_abs_params(priv, dev1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) 	if (priv->flags & ALPS_WHEEL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) 		dev1->evbit[BIT_WORD(EV_REL)] |= BIT_MASK(EV_REL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) 		dev1->relbit[BIT_WORD(REL_WHEEL)] |= BIT_MASK(REL_WHEEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) 	if (priv->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) 		dev1->keybit[BIT_WORD(BTN_FORWARD)] |= BIT_MASK(BTN_FORWARD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) 		dev1->keybit[BIT_WORD(BTN_BACK)] |= BIT_MASK(BTN_BACK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) 	if (priv->flags & ALPS_FOUR_BUTTONS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) 		dev1->keybit[BIT_WORD(BTN_0)] |= BIT_MASK(BTN_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) 		dev1->keybit[BIT_WORD(BTN_1)] |= BIT_MASK(BTN_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) 		dev1->keybit[BIT_WORD(BTN_2)] |= BIT_MASK(BTN_2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) 		dev1->keybit[BIT_WORD(BTN_3)] |= BIT_MASK(BTN_3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) 	} else if (priv->flags & ALPS_BUTTONPAD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) 		set_bit(INPUT_PROP_BUTTONPAD, dev1->propbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) 		clear_bit(BTN_RIGHT, dev1->keybit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) 		dev1->keybit[BIT_WORD(BTN_MIDDLE)] |= BIT_MASK(BTN_MIDDLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) 	if (priv->flags & ALPS_DUALPOINT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) 		struct input_dev *dev2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) 		dev2 = input_allocate_device();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) 		if (!dev2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) 			psmouse_err(psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) 				    "failed to allocate trackstick device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) 			error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) 			goto init_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) 		snprintf(priv->phys2, sizeof(priv->phys2), "%s/input1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) 			 psmouse->ps2dev.serio->phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) 		dev2->phys = priv->phys2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) 		 * format of input device name is: "protocol vendor name"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) 		 * see function psmouse_switch_protocol() in psmouse-base.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) 		dev2->name = "AlpsPS/2 ALPS DualPoint Stick";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) 		dev2->id.bustype = BUS_I8042;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) 		dev2->id.vendor  = 0x0002;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) 		dev2->id.product = PSMOUSE_ALPS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) 		dev2->id.version = priv->proto_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) 		dev2->dev.parent = &psmouse->ps2dev.serio->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) 		input_set_capability(dev2, EV_REL, REL_X);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) 		input_set_capability(dev2, EV_REL, REL_Y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) 		if (priv->flags & ALPS_DUALPOINT_WITH_PRESSURE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) 			input_set_capability(dev2, EV_ABS, ABS_PRESSURE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) 			input_set_abs_params(dev2, ABS_PRESSURE, 0, 127, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) 		input_set_capability(dev2, EV_KEY, BTN_LEFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) 		input_set_capability(dev2, EV_KEY, BTN_RIGHT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) 		input_set_capability(dev2, EV_KEY, BTN_MIDDLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) 		__set_bit(INPUT_PROP_POINTER, dev2->propbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) 		__set_bit(INPUT_PROP_POINTING_STICK, dev2->propbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) 		error = input_register_device(dev2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) 		if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) 			psmouse_err(psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) 				    "failed to register trackstick device: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) 				    error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) 			input_free_device(dev2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) 			goto init_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) 		priv->dev2 = dev2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) 	priv->psmouse = psmouse;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) 	INIT_DELAYED_WORK(&priv->dev3_register_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) 			  alps_register_bare_ps2_mouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) 	psmouse->protocol_handler = alps_process_byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) 	psmouse->poll = alps_poll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) 	psmouse->disconnect = alps_disconnect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) 	psmouse->reconnect = alps_reconnect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) 	psmouse->pktsize = priv->proto_version == ALPS_PROTO_V4 ? 8 : 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) 	/* We are having trouble resyncing ALPS touchpads so disable it for now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) 	psmouse->resync_time = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) 	/* Allow 2 invalid packets without resetting device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) 	psmouse->resetafter = psmouse->pktsize * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) init_fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) 	psmouse_reset(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) 	 * Even though we did not allocate psmouse->private we do free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) 	 * it here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) 	kfree(psmouse->private);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) 	psmouse->private = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) int alps_detect(struct psmouse *psmouse, bool set_properties)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) 	struct alps_data *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) 	error = alps_identify(psmouse, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) 	 * ALPS cs19 is a trackpoint-only device, and uses different
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) 	 * protocol than DualPoint ones, so we return -EINVAL here and let
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) 	 * trackpoint.c drive this device. If the trackpoint driver is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) 	 * enabled, the device will fall back to a bare PS/2 mouse.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) 	 * If ps2_command() fails here, we depend on the immediately
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) 	 * followed psmouse_reset() to reset the device to normal state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) 	if (alps_is_cs19_trackpoint(psmouse)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) 		psmouse_dbg(psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) 			    "ALPS CS19 trackpoint-only device detected, ignoring\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) 	 * Reset the device to make sure it is fully operational:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) 	 * on some laptops, like certain Dell Latitudes, we may
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) 	 * fail to properly detect presence of trackstick if device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) 	 * has not been reset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) 	psmouse_reset(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) 	priv = kzalloc(sizeof(struct alps_data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) 	if (!priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) 	error = alps_identify(psmouse, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) 	if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) 		kfree(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) 	if (set_properties) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) 		psmouse->vendor = "ALPS";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) 		psmouse->name = priv->flags & ALPS_DUALPOINT ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) 				"DualPoint TouchPad" : "GlidePoint";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) 		psmouse->model = priv->proto_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) 		 * Destroy alps_data structure we allocated earlier since
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) 		 * this was just a "trial run". Otherwise we'll keep it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) 		 * to be used by alps_init() which has to be called if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) 		 * we succeed and set_properties is true.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) 		kfree(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) 		psmouse->private = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232)