From d7c13d3470bcd7fceb7ad53b0fea195f1606a40b Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 13 Jan 2015 20:53:22 -0800 Subject: Input: ALPS - renumber protocol numbers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In order to accommodate new protocol number for Rushmore touchpads let's shift protocol numbers by 8 bits (i.e. 1 -> 0x100) - this way we keep protocol version reported in input device id the same as it was, but add some holes in numbering. Tested-by: Pali Rohár Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/alps.c | 2 +- drivers/input/mouse/alps.h | 30 +++++++++++++++--------------- 2 files changed, 16 insertions(+), 16 deletions(-) (limited to 'drivers/input/mouse') diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index f205b8be2ce..92a886b0eca 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -2526,7 +2526,7 @@ int alps_detect(struct psmouse *psmouse, bool set_properties) psmouse->vendor = "ALPS"; psmouse->name = dummy.flags & ALPS_DUALPOINT ? "DualPoint TouchPad" : "GlidePoint"; - psmouse->model = dummy.proto_version << 8; + psmouse->model = dummy.proto_version; } return 0; } diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h index 66240b47819..94645bfa2a0 100644 --- a/drivers/input/mouse/alps.h +++ b/drivers/input/mouse/alps.h @@ -14,13 +14,13 @@ #include -#define ALPS_PROTO_V1 1 -#define ALPS_PROTO_V2 2 -#define ALPS_PROTO_V3 3 -#define ALPS_PROTO_V4 4 -#define ALPS_PROTO_V5 5 -#define ALPS_PROTO_V6 6 -#define ALPS_PROTO_V7 7 /* t3btl t4s */ +#define ALPS_PROTO_V1 0x100 +#define ALPS_PROTO_V2 0x200 +#define ALPS_PROTO_V3 0x300 +#define ALPS_PROTO_V4 0x400 +#define ALPS_PROTO_V5 0x500 +#define ALPS_PROTO_V6 0x600 +#define ALPS_PROTO_V7 0x700 /* t3btl t4s */ #define MAX_TOUCHES 2 @@ -64,11 +64,11 @@ enum V7_PACKET_ID { * lists a number of such touchpads. */ struct alps_model_info { - unsigned char signature[3]; - unsigned char command_mode_resp; - unsigned char proto_version; - unsigned char byte0, mask0; - int flags; + u8 signature[3]; + u8 command_mode_resp; + u16 proto_version; + u8 byte0, mask0; + unsigned int flags; }; /** @@ -166,9 +166,9 @@ struct alps_data { /* these are autodetected when the device is identified */ const struct alps_nibble_commands *nibble_commands; int addr_command; - unsigned char proto_version; - unsigned char byte0, mask0; - unsigned char fw_ver[3]; + u16 proto_version; + u8 byte0, mask0; + u8 fw_ver[3]; int flags; int x_max; int y_max; -- cgit v1.2.3-70-g09d2 From fb2dd7a61d6f1590b183199b29a065d14f2627b5 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 14 Jan 2015 10:39:52 -0800 Subject: Input: ALPS - make Rushmore a separate protocol MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Even though Rushmore is very close to V3 protocol it is sufficiently different to warrant it's own protocol name. Tested-by: Pali Rohár Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/alps.c | 29 ++++++++++++++++++----------- drivers/input/mouse/alps.h | 1 + 2 files changed, 19 insertions(+), 11 deletions(-) (limited to 'drivers/input/mouse') diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 92a886b0eca..720fb6682f3 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -99,7 +99,6 @@ static const struct alps_nibble_commands alps_v6_nibble_commands[] = { #define ALPS_FOUR_BUTTONS 0x40 /* 4 direction button present */ #define ALPS_PS2_INTERLEAVED 0x80 /* 3-byte PS/2 packet interleaved with 6-byte ALPS packet */ -#define ALPS_IS_RUSHMORE 0x100 /* device is a rushmore */ #define ALPS_BUTTONPAD 0x200 /* device is a clickpad */ static const struct alps_model_info alps_model_data[] = { @@ -412,7 +411,7 @@ static int alps_process_bitmap(struct alps_data *priv, (2 * (priv->y_bits - 1)); /* y-bitmap order is reversed, except on rushmore */ - if (!(priv->flags & ALPS_IS_RUSHMORE)) { + if (priv->proto_version != ALPS_PROTO_V3_RUSHMORE) { fields->mt[0].y = priv->y_max - fields->mt[0].y; fields->mt[1].y = priv->y_max - fields->mt[1].y; } @@ -648,7 +647,8 @@ static void alps_process_touchpad_packet_v3_v5(struct psmouse *psmouse) */ if (f->is_mp) { fingers = f->fingers; - if (priv->proto_version == ALPS_PROTO_V3) { + if (priv->proto_version == ALPS_PROTO_V3 || + priv->proto_version == ALPS_PROTO_V3_RUSHMORE) { if (alps_process_bitmap(priv, f) == 0) fingers = 0; /* Use st data */ @@ -1275,7 +1275,7 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse) psmouse->pktcnt - 1, psmouse->packet[psmouse->pktcnt - 1]); - if (priv->proto_version == ALPS_PROTO_V3 && + if (priv->proto_version == ALPS_PROTO_V3_RUSHMORE && psmouse->pktcnt == psmouse->pktsize) { /* * Some Dell boxes, such as Latitude E6440 or E7440 @@ -2182,6 +2182,7 @@ static void alps_set_defaults(struct alps_data *priv) priv->x_max = 1023; priv->y_max = 767; break; + case ALPS_PROTO_V3: priv->hw_init = alps_hw_init_v3; priv->process_packet = alps_process_packet_v3; @@ -2190,6 +2191,18 @@ static void alps_set_defaults(struct alps_data *priv) priv->nibble_commands = alps_v3_nibble_commands; priv->addr_command = PSMOUSE_CMD_RESET_WRAP; break; + + case ALPS_PROTO_V3_RUSHMORE: + priv->hw_init = alps_hw_init_rushmore_v3; + priv->process_packet = alps_process_packet_v3; + priv->set_abs_params = alps_set_abs_params_mt; + priv->decode_fields = alps_decode_rushmore; + priv->nibble_commands = alps_v3_nibble_commands; + priv->addr_command = PSMOUSE_CMD_RESET_WRAP; + priv->x_bits = 16; + priv->y_bits = 12; + break; + case ALPS_PROTO_V4: priv->hw_init = alps_hw_init_v4; priv->process_packet = alps_process_packet_v4; @@ -2313,15 +2326,9 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv) return 0; } else if (ec[0] == 0x88 && ec[1] == 0x08) { - priv->proto_version = ALPS_PROTO_V3; + priv->proto_version = ALPS_PROTO_V3_RUSHMORE; alps_set_defaults(priv); - priv->hw_init = alps_hw_init_rushmore_v3; - priv->decode_fields = alps_decode_rushmore; - priv->x_bits = 16; - priv->y_bits = 12; - priv->flags |= ALPS_IS_RUSHMORE; - /* hack to make addr_command, nibble_command available */ psmouse->private = priv; diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h index 94645bfa2a0..f19908abfb1 100644 --- a/drivers/input/mouse/alps.h +++ b/drivers/input/mouse/alps.h @@ -17,6 +17,7 @@ #define ALPS_PROTO_V1 0x100 #define ALPS_PROTO_V2 0x200 #define ALPS_PROTO_V3 0x300 +#define ALPS_PROTO_V3_RUSHMORE 0x310 #define ALPS_PROTO_V4 0x400 #define ALPS_PROTO_V5 0x500 #define ALPS_PROTO_V6 0x600 -- cgit v1.2.3-70-g09d2 From 8326bb5741f3f72f7b789614e620d9f7c2ddc2ba Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 13 Jan 2015 21:08:00 -0800 Subject: Input: ALPS - split protocol data from model info MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In preparation of reworking the way we set protocol parameters let's split certain protocol items from alps_model_info into a separate structure. Tested-by: Pali Rohár Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/alps.c | 58 +++++++++++++++++++++++----------------------- drivers/input/mouse/alps.h | 26 ++++++++++++++------- 2 files changed, 46 insertions(+), 38 deletions(-) (limited to 'drivers/input/mouse') diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 720fb6682f3..6ad2cd733a4 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -102,32 +102,32 @@ static const struct alps_nibble_commands alps_v6_nibble_commands[] = { #define ALPS_BUTTONPAD 0x200 /* device is a clickpad */ static const struct alps_model_info alps_model_data[] = { - { { 0x32, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Toshiba Salellite Pro M10 */ - { { 0x33, 0x02, 0x0a }, 0x00, ALPS_PROTO_V1, 0x88, 0xf8, 0 }, /* UMAX-530T */ - { { 0x53, 0x02, 0x0a }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 }, - { { 0x53, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 }, - { { 0x60, 0x03, 0xc8 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 }, /* HP ze1115 */ - { { 0x63, 0x02, 0x0a }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 }, - { { 0x63, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 }, - { { 0x63, 0x02, 0x28 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_FW_BK_2 }, /* Fujitsu Siemens S6010 */ - { { 0x63, 0x02, 0x3c }, 0x00, ALPS_PROTO_V2, 0x8f, 0x8f, ALPS_WHEEL }, /* Toshiba Satellite S2400-103 */ - { { 0x63, 0x02, 0x50 }, 0x00, ALPS_PROTO_V2, 0xef, 0xef, ALPS_FW_BK_1 }, /* NEC Versa L320 */ - { { 0x63, 0x02, 0x64 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 }, - { { 0x63, 0x03, 0xc8 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D800 */ - { { 0x73, 0x00, 0x0a }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_DUALPOINT }, /* ThinkPad R61 8918-5QG */ - { { 0x73, 0x02, 0x0a }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 }, - { { 0x73, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_FW_BK_2 }, /* Ahtec Laptop */ - { { 0x20, 0x02, 0x0e }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* XXX */ - { { 0x22, 0x02, 0x0a }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, - { { 0x22, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D600 */ + { { 0x32, 0x02, 0x14 }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT } }, /* Toshiba Salellite Pro M10 */ + { { 0x33, 0x02, 0x0a }, 0x00, { ALPS_PROTO_V1, 0x88, 0xf8, 0 } }, /* UMAX-530T */ + { { 0x53, 0x02, 0x0a }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, 0 } }, + { { 0x53, 0x02, 0x14 }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, 0 } }, + { { 0x60, 0x03, 0xc8 }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, 0 } }, /* HP ze1115 */ + { { 0x63, 0x02, 0x0a }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, 0 } }, + { { 0x63, 0x02, 0x14 }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, 0 } }, + { { 0x63, 0x02, 0x28 }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_FW_BK_2 } }, /* Fujitsu Siemens S6010 */ + { { 0x63, 0x02, 0x3c }, 0x00, { ALPS_PROTO_V2, 0x8f, 0x8f, ALPS_WHEEL } }, /* Toshiba Satellite S2400-103 */ + { { 0x63, 0x02, 0x50 }, 0x00, { ALPS_PROTO_V2, 0xef, 0xef, ALPS_FW_BK_1 } }, /* NEC Versa L320 */ + { { 0x63, 0x02, 0x64 }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, 0 } }, + { { 0x63, 0x03, 0xc8 }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT } }, /* Dell Latitude D800 */ + { { 0x73, 0x00, 0x0a }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_DUALPOINT } }, /* ThinkPad R61 8918-5QG */ + { { 0x73, 0x02, 0x0a }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, 0 } }, + { { 0x73, 0x02, 0x14 }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_FW_BK_2 } }, /* Ahtec Laptop */ + { { 0x20, 0x02, 0x0e }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT } }, /* XXX */ + { { 0x22, 0x02, 0x0a }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT } }, + { { 0x22, 0x02, 0x14 }, 0x00, { ALPS_PROTO_V2, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT } }, /* Dell Latitude D600 */ /* Dell Latitude E5500, E6400, E6500, Precision M4400 */ - { { 0x62, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xcf, 0xcf, - ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, - { { 0x73, 0x00, 0x14 }, 0x00, ALPS_PROTO_V6, 0xff, 0xff, ALPS_DUALPOINT }, /* Dell XT2 */ - { { 0x73, 0x02, 0x50 }, 0x00, ALPS_PROTO_V2, 0xcf, 0xcf, ALPS_FOUR_BUTTONS }, /* Dell Vostro 1400 */ - { { 0x52, 0x01, 0x14 }, 0x00, ALPS_PROTO_V2, 0xff, 0xff, - ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, /* Toshiba Tecra A11-11L */ - { { 0x73, 0x02, 0x64 }, 0x8a, ALPS_PROTO_V4, 0x8f, 0x8f, 0 }, + { { 0x62, 0x02, 0x14 }, 0x00, { ALPS_PROTO_V2, 0xcf, 0xcf, + ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED } }, + { { 0x73, 0x00, 0x14 }, 0x00, { ALPS_PROTO_V6, 0xff, 0xff, ALPS_DUALPOINT } }, /* Dell XT2 */ + { { 0x73, 0x02, 0x50 }, 0x00, { ALPS_PROTO_V2, 0xcf, 0xcf, ALPS_FOUR_BUTTONS } }, /* Dell Vostro 1400 */ + { { 0x52, 0x01, 0x14 }, 0x00, { ALPS_PROTO_V2, 0xff, 0xff, + ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED } }, /* Toshiba Tecra A11-11L */ + { { 0x73, 0x02, 0x64 }, 0x8a, { ALPS_PROTO_V4, 0x8f, 0x8f, 0 } }, }; static void alps_set_abs_params_st(struct alps_data *priv, @@ -2264,12 +2264,12 @@ static int alps_match_table(struct psmouse *psmouse, struct alps_data *priv, (!model->command_mode_resp || model->command_mode_resp == ec[2])) { - priv->proto_version = model->proto_version; + priv->proto_version = model->protocol_info.version; alps_set_defaults(priv); - priv->flags = model->flags; - priv->byte0 = model->byte0; - priv->mask0 = model->mask0; + priv->flags = model->protocol_info.flags; + priv->byte0 = model->protocol_info.byte0; + priv->mask0 = model->protocol_info.mask0; return 0; } diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h index f19908abfb1..c7952356260 100644 --- a/drivers/input/mouse/alps.h +++ b/drivers/input/mouse/alps.h @@ -46,6 +46,21 @@ enum V7_PACKET_ID { V7_PACKET_ID_UNKNOWN, }; +/** + * struct alps_protocol_info - information about protocol used by a device + * @version: Indicates V1/V2/V3/... + * @byte0: Helps figure out whether a position report packet matches the + * known format for this model. The first byte of the report, ANDed with + * mask0, should match byte0. + * @mask0: The mask used to check the first byte of the report. + * @flags: Additional device capabilities (passthrough port, trackstick, etc.). + */ +struct alps_protocol_info { + u16 version; + u8 byte0, mask0; + unsigned int flags; +}; + /** * struct alps_model_info - touchpad ID table * @signature: E7 response string to match. @@ -53,12 +68,7 @@ enum V7_PACKET_ID { * (aka command mode response) identifies the firmware minor version. This * can be used to distinguish different hardware models which are not * uniquely identifiable through their E7 responses. - * @proto_version: Indicates V1/V2/V3/... - * @byte0: Helps figure out whether a position report packet matches the - * known format for this model. The first byte of the report, ANDed with - * mask0, should match byte0. - * @mask0: The mask used to check the first byte of the report. - * @flags: Additional device capabilities (passthrough port, trackstick, etc.). + * @protocol_info: information about protcol used by the device. * * Many (but not all) ALPS touchpads can be identified by looking at the * values returned in the "E7 report" and/or the "EC report." This table @@ -67,9 +77,7 @@ enum V7_PACKET_ID { struct alps_model_info { u8 signature[3]; u8 command_mode_resp; - u16 proto_version; - u8 byte0, mask0; - unsigned int flags; + struct alps_protocol_info protocol_info; }; /** -- cgit v1.2.3-70-g09d2 From 3296f71cd2fde7a2ad52e66a27eae419f6328066 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 12 Jan 2015 00:30:32 -0800 Subject: Input: ALPS - consolidate setting protocol parameters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move setting of all protocol properties into alps_set_protocol (former alps_set_defaults) instead of having it split between several functions. Tested-by: Pali Rohár Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/alps.c | 131 +++++++++++++++++++++++---------------------- 1 file changed, 67 insertions(+), 64 deletions(-) (limited to 'drivers/input/mouse') diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 6ad2cd733a4..b97832b622c 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -130,6 +130,22 @@ static const struct alps_model_info alps_model_data[] = { { { 0x73, 0x02, 0x64 }, 0x8a, { ALPS_PROTO_V4, 0x8f, 0x8f, 0 } }, }; +static const struct alps_protocol_info alps_v3_protocol_data = { + ALPS_PROTO_V3, 0x8f, 0x8f, ALPS_DUALPOINT +}; + +static const struct alps_protocol_info alps_v3_rushmore_data = { + ALPS_PROTO_V3_RUSHMORE, 0x8f, 0x8f, ALPS_DUALPOINT +}; + +static const struct alps_protocol_info alps_v5_protocol_data = { + ALPS_PROTO_V5, 0xc8, 0xd8, 0 +}; + +static const struct alps_protocol_info alps_v7_protocol_data = { + ALPS_PROTO_V7, 0x48, 0x48, ALPS_DUALPOINT +}; + static void alps_set_abs_params_st(struct alps_data *priv, struct input_dev *dev1); static void alps_set_abs_params_mt(struct alps_data *priv, @@ -2162,11 +2178,18 @@ error: return ret; } -static void alps_set_defaults(struct alps_data *priv) +static int alps_set_protocol(struct psmouse *psmouse, + struct alps_data *priv, + const struct alps_protocol_info *protocol) { - priv->byte0 = 0x8f; - priv->mask0 = 0x8f; - priv->flags = ALPS_DUALPOINT; + psmouse->private = priv; + + setup_timer(&priv->timer, alps_flush_packet, (unsigned long)psmouse); + + priv->proto_version = protocol->version; + priv->byte0 = protocol->byte0; + priv->mask0 = protocol->mask0; + priv->flags = protocol->flags; priv->x_max = 2000; priv->y_max = 1400; @@ -2201,6 +2224,11 @@ static void alps_set_defaults(struct alps_data *priv) priv->addr_command = PSMOUSE_CMD_RESET_WRAP; priv->x_bits = 16; priv->y_bits = 12; + + if (alps_probe_trackstick_v3(psmouse, + ALPS_REG_BASE_RUSHMORE) < 0) + priv->flags &= ~ALPS_DUALPOINT; + break; case ALPS_PROTO_V4: @@ -2210,6 +2238,7 @@ static void alps_set_defaults(struct alps_data *priv) priv->nibble_commands = alps_v4_nibble_commands; priv->addr_command = PSMOUSE_CMD_DISABLE; break; + case ALPS_PROTO_V5: priv->hw_init = alps_hw_init_dolphin_v1; priv->process_packet = alps_process_touchpad_packet_v3_v5; @@ -2217,14 +2246,12 @@ static void alps_set_defaults(struct alps_data *priv) priv->set_abs_params = alps_set_abs_params_mt; priv->nibble_commands = alps_v3_nibble_commands; priv->addr_command = PSMOUSE_CMD_RESET_WRAP; - priv->byte0 = 0xc8; - priv->mask0 = 0xd8; - priv->flags = 0; priv->x_max = 1360; priv->y_max = 660; priv->x_bits = 23; priv->y_bits = 12; break; + case ALPS_PROTO_V6: priv->hw_init = alps_hw_init_v6; priv->process_packet = alps_process_packet_v6; @@ -2233,6 +2260,7 @@ static void alps_set_defaults(struct alps_data *priv) priv->x_max = 2047; priv->y_max = 1535; break; + case ALPS_PROTO_V7: priv->hw_init = alps_hw_init_v7; priv->process_packet = alps_process_packet_v7; @@ -2240,19 +2268,21 @@ static void alps_set_defaults(struct alps_data *priv) priv->set_abs_params = alps_set_abs_params_mt; priv->nibble_commands = alps_v3_nibble_commands; priv->addr_command = PSMOUSE_CMD_RESET_WRAP; - priv->x_max = 0xfff; - priv->y_max = 0x7ff; - priv->byte0 = 0x48; - priv->mask0 = 0x48; + + if (alps_dolphin_get_device_area(psmouse, priv)) + return -EIO; if (priv->fw_ver[1] != 0xba) priv->flags |= ALPS_BUTTONPAD; + break; } + + return 0; } -static int alps_match_table(struct psmouse *psmouse, struct alps_data *priv, - unsigned char *e7, unsigned char *ec) +static const struct alps_protocol_info *alps_match_table(unsigned char *e7, + unsigned char *ec) { const struct alps_model_info *model; int i; @@ -2264,22 +2294,16 @@ static int alps_match_table(struct psmouse *psmouse, struct alps_data *priv, (!model->command_mode_resp || model->command_mode_resp == ec[2])) { - priv->proto_version = model->protocol_info.version; - alps_set_defaults(priv); - - priv->flags = model->protocol_info.flags; - priv->byte0 = model->protocol_info.byte0; - priv->mask0 = model->protocol_info.mask0; - - return 0; + return &model->protocol_info; } } - return -EINVAL; + return NULL; } static int alps_identify(struct psmouse *psmouse, struct alps_data *priv) { + const struct alps_protocol_info *protocol; unsigned char e6[4], e7[4], ec[4]; /* @@ -2306,48 +2330,30 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv) alps_exit_command_mode(psmouse)) return -EIO; - /* Save the Firmware version */ - memcpy(priv->fw_ver, ec, 3); - - if (alps_match_table(psmouse, priv, e7, ec) == 0) { - return 0; - } else if (e7[0] == 0x73 && e7[1] == 0x03 && e7[2] == 0x50 && - ec[0] == 0x73 && (ec[1] == 0x01 || ec[1] == 0x02)) { - priv->proto_version = ALPS_PROTO_V5; - alps_set_defaults(priv); - if (alps_dolphin_get_device_area(psmouse, priv)) - return -EIO; - else - return 0; - } else if (ec[0] == 0x88 && - ((ec[1] & 0xf0) == 0xb0 || (ec[1] & 0xf0) == 0xc0)) { - priv->proto_version = ALPS_PROTO_V7; - alps_set_defaults(priv); - - return 0; - } else if (ec[0] == 0x88 && ec[1] == 0x08) { - priv->proto_version = ALPS_PROTO_V3_RUSHMORE; - alps_set_defaults(priv); - - /* hack to make addr_command, nibble_command available */ - psmouse->private = priv; - - if (alps_probe_trackstick_v3(psmouse, ALPS_REG_BASE_RUSHMORE)) - priv->flags &= ~ALPS_DUALPOINT; - - return 0; - } else if (ec[0] == 0x88 && ec[1] == 0x07 && - ec[2] >= 0x90 && ec[2] <= 0x9d) { - priv->proto_version = ALPS_PROTO_V3; - alps_set_defaults(priv); - - return 0; + protocol = alps_match_table(e7, ec); + if (!protocol) { + if (e7[0] == 0x73 && e7[1] == 0x03 && e7[2] == 0x50 && + ec[0] == 0x73 && (ec[1] == 0x01 || ec[1] == 0x02)) { + protocol = &alps_v5_protocol_data; + } else if (ec[0] == 0x88 && + ((ec[1] & 0xf0) == 0xb0 || (ec[1] & 0xf0) == 0xc0)) { + protocol = &alps_v7_protocol_data; + } else if (ec[0] == 0x88 && ec[1] == 0x08) { + protocol = &alps_v3_rushmore_data; + } else if (ec[0] == 0x88 && ec[1] == 0x07 && + ec[2] >= 0x90 && ec[2] <= 0x9d) { + protocol = &alps_v3_protocol_data; + } else { + psmouse_dbg(psmouse, + "Likely not an ALPS touchpad: E7=%3ph, EC=%3ph\n", e7, ec); + return -EINVAL; + } } - psmouse_dbg(psmouse, - "Likely not an ALPS touchpad: E7=%3ph, EC=%3ph\n", e7, ec); + /* Save the Firmware version */ + memcpy(priv->fw_ver, ec, 3); - return -EINVAL; + return alps_set_protocol(psmouse, priv, protocol); } static int alps_reconnect(struct psmouse *psmouse) @@ -2410,9 +2416,6 @@ int alps_init(struct psmouse *psmouse) goto init_fail; priv->dev2 = dev2; - setup_timer(&priv->timer, alps_flush_packet, (unsigned long)psmouse); - - psmouse->private = priv; psmouse_reset(psmouse); -- cgit v1.2.3-70-g09d2 From a09221e83e13e09a33109b9b037484eade901cea Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 13 Jan 2015 20:46:09 -0800 Subject: Input: ALPS - fix trackstick detection on some Dell Latitudes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On some Dell Latitudes we fail to identify presence of trackstick unless we reset the device. The issue is quite benign as we do perform reset in alps_init(), so the trackstick ends up working, but mouse name reported to userspace is not accurate. In order to fix the issue while avoiding the additional lengthy reset we move the resrt to alps_detect() and keep the discovered state to be used later in alps_init(). Reported-by: Pali Rohár Tested-by: Pali Rohár Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/alps.c | 78 +++++++++++++++++++++++++++++++++------------- 1 file changed, 56 insertions(+), 22 deletions(-) (limited to 'drivers/input/mouse') diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index b97832b622c..d164690bfdf 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -1796,7 +1796,7 @@ static int alps_setup_trackstick_v3(struct psmouse *psmouse, int reg_base) * all. */ if (alps_rpt_cmd(psmouse, 0, PSMOUSE_CMD_SETSCALE21, param)) { - psmouse_warn(psmouse, "trackstick E7 report failed\n"); + psmouse_warn(psmouse, "Failed to initialize trackstick (E7 report failed)\n"); ret = -ENODEV; } else { psmouse_dbg(psmouse, "trackstick E7 report: %3ph\n", param); @@ -1961,8 +1961,6 @@ static int alps_hw_init_rushmore_v3(struct psmouse *psmouse) ALPS_REG_BASE_RUSHMORE); if (reg_val == -EIO) goto error; - if (reg_val == -ENODEV) - priv->flags &= ~ALPS_DUALPOINT; } if (alps_enter_command_mode(psmouse) || @@ -2305,6 +2303,7 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv) { const struct alps_protocol_info *protocol; unsigned char e6[4], e7[4], ec[4]; + int error; /* * First try "E6 report". @@ -2350,10 +2349,15 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv) } } - /* Save the Firmware version */ - memcpy(priv->fw_ver, ec, 3); + if (priv) { + /* Save the Firmware version */ + memcpy(priv->fw_ver, ec, 3); + error = alps_set_protocol(psmouse, priv, protocol); + if (error) + return error; + } - return alps_set_protocol(psmouse, priv, protocol); + return 0; } static int alps_reconnect(struct psmouse *psmouse) @@ -2407,22 +2411,20 @@ static void alps_set_abs_params_mt(struct alps_data *priv, int alps_init(struct psmouse *psmouse) { - struct alps_data *priv; + struct alps_data *priv = psmouse->private; struct input_dev *dev1 = psmouse->dev, *dev2; + int error; - priv = kzalloc(sizeof(struct alps_data), GFP_KERNEL); dev2 = input_allocate_device(); - if (!priv || !dev2) + if (!dev2) { + error = -ENOMEM; goto init_fail; + } priv->dev2 = dev2; - psmouse_reset(psmouse); - - if (alps_identify(psmouse, priv) < 0) - goto init_fail; - - if (priv->hw_init(psmouse)) + error = priv->hw_init(psmouse); + if (error) goto init_fail; /* @@ -2520,24 +2522,56 @@ int alps_init(struct psmouse *psmouse) init_fail: psmouse_reset(psmouse); input_free_device(dev2); - kfree(priv); + /* + * Even though we did not allocate psmouse->private we do free + * it here. + */ + kfree(psmouse->private); psmouse->private = NULL; - return -1; + return error; } int alps_detect(struct psmouse *psmouse, bool set_properties) { - struct alps_data dummy; + struct alps_data *priv; + int error; - if (alps_identify(psmouse, &dummy) < 0) - return -1; + error = alps_identify(psmouse, NULL); + if (error) + return error; + + /* + * Reset the device to make sure it is fully operational: + * on some laptops, like certain Dell Latitudes, we may + * fail to properly detect presence of trackstick if device + * has not been reset. + */ + psmouse_reset(psmouse); + + priv = kzalloc(sizeof(struct alps_data), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + error = alps_identify(psmouse, priv); + if (error) + return error; if (set_properties) { psmouse->vendor = "ALPS"; - psmouse->name = dummy.flags & ALPS_DUALPOINT ? + psmouse->name = priv->flags & ALPS_DUALPOINT ? "DualPoint TouchPad" : "GlidePoint"; - psmouse->model = dummy.proto_version; + psmouse->model = priv->proto_version; + } else { + /* + * Destroy alps_data structure we allocated earlier since + * this was just a "trial run". Otherwise we'll keep it + * to be used by alps_init() which has to be called if + * we succeed and set_properties is true. + */ + kfree(priv); + psmouse->private = NULL; } + return 0; } -- cgit v1.2.3-70-g09d2 From 04aae283ba6a8cd4851d937bf9c6d6ef0361d794 Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Wed, 14 Jan 2015 13:18:30 -0800 Subject: Input: ALPS - do not mix trackstick and external PS/2 mouse data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously dev2 device was used for both external PS/2 mouse and internal trackstick device (if available). This change introduces dev3 device which is used for external PS/2 mouse data and dev2 is now used only for trackstick. In case that trackstick is not present dev2 is not created, so userspace does not see non existent device in system. Because laptops with ALPS devices often do not use i8042 active multiplexing all data (from touchpad, trackstick and external PS/2 mouse) come to one port. So it is not possible to know if external PS/2 mouse is connected or not. In most cases external PS/2 mouse is not connected so driver will create dev3 input device after first bare PS/2 packet will be received. So there will not be "ghost" input device. This change also helps in identifying possible problems in future if driver decides to report 6-bytes trackstick packets as 3-bytes bare PS/2 (data will be reported to dev3 instead dev2). Signed-off-by: Pali Rohár Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/alps.c | 190 +++++++++++++++++++++++++++++++++------------ drivers/input/mouse/alps.h | 14 +++- 2 files changed, 151 insertions(+), 53 deletions(-) (limited to 'drivers/input/mouse') diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index d164690bfdf..a4d69ef0f84 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -165,8 +165,7 @@ static bool alps_is_valid_first_byte(struct alps_data *priv, return (data & priv->mask0) == priv->byte0; } -static void alps_report_buttons(struct psmouse *psmouse, - struct input_dev *dev1, struct input_dev *dev2, +static void alps_report_buttons(struct input_dev *dev1, struct input_dev *dev2, int left, int right, int middle) { struct input_dev *dev; @@ -176,20 +175,21 @@ static void alps_report_buttons(struct psmouse *psmouse, * other device (dev2) then this event should be also * sent through that device. */ - dev = test_bit(BTN_LEFT, dev2->key) ? dev2 : dev1; + dev = (dev2 && test_bit(BTN_LEFT, dev2->key)) ? dev2 : dev1; input_report_key(dev, BTN_LEFT, left); - dev = test_bit(BTN_RIGHT, dev2->key) ? dev2 : dev1; + dev = (dev2 && test_bit(BTN_RIGHT, dev2->key)) ? dev2 : dev1; input_report_key(dev, BTN_RIGHT, right); - dev = test_bit(BTN_MIDDLE, dev2->key) ? dev2 : dev1; + dev = (dev2 && test_bit(BTN_MIDDLE, dev2->key)) ? dev2 : dev1; input_report_key(dev, BTN_MIDDLE, middle); /* * Sync the _other_ device now, we'll do the first * device later once we report the rest of the events. */ - input_sync(dev2); + if (dev2) + input_sync(dev2); } static void alps_process_packet_v1_v2(struct psmouse *psmouse) @@ -236,13 +236,13 @@ static void alps_process_packet_v1_v2(struct psmouse *psmouse) input_report_rel(dev2, REL_X, (x > 383 ? (x - 768) : x)); input_report_rel(dev2, REL_Y, -(y > 255 ? (y - 512) : y)); - alps_report_buttons(psmouse, dev2, dev, left, right, middle); + alps_report_buttons(dev2, dev, left, right, middle); input_sync(dev2); return; } - alps_report_buttons(psmouse, dev, dev2, left, right, middle); + alps_report_buttons(dev, dev2, left, right, middle); /* Convert hardware tap to a reasonable Z value */ if (ges && !fin) @@ -1123,23 +1123,89 @@ static void alps_process_packet_v7(struct psmouse *psmouse) alps_process_touchpad_packet_v7(psmouse); } -static void alps_report_bare_ps2_packet(struct psmouse *psmouse, +static DEFINE_MUTEX(alps_mutex); + +static void alps_register_bare_ps2_mouse(struct work_struct *work) +{ + struct alps_data *priv = + container_of(work, struct alps_data, dev3_register_work.work); + struct psmouse *psmouse = priv->psmouse; + struct input_dev *dev3; + int error = 0; + + mutex_lock(&alps_mutex); + + if (priv->dev3) + goto out; + + dev3 = input_allocate_device(); + if (!dev3) { + psmouse_err(psmouse, "failed to allocate secondary device\n"); + error = -ENOMEM; + goto out; + } + + snprintf(priv->phys3, sizeof(priv->phys3), "%s/%s", + psmouse->ps2dev.serio->phys, + (priv->dev2 ? "input2" : "input1")); + dev3->phys = priv->phys3; + + /* + * format of input device name is: "protocol vendor name" + * see function psmouse_switch_protocol() in psmouse-base.c + */ + dev3->name = "PS/2 ALPS Mouse"; + + dev3->id.bustype = BUS_I8042; + dev3->id.vendor = 0x0002; + dev3->id.product = PSMOUSE_PS2; + dev3->id.version = 0x0000; + dev3->dev.parent = &psmouse->ps2dev.serio->dev; + + input_set_capability(dev3, EV_REL, REL_X); + input_set_capability(dev3, EV_REL, REL_Y); + input_set_capability(dev3, EV_KEY, BTN_LEFT); + input_set_capability(dev3, EV_KEY, BTN_RIGHT); + input_set_capability(dev3, EV_KEY, BTN_MIDDLE); + + __set_bit(INPUT_PROP_POINTER, dev3->propbit); + + error = input_register_device(dev3); + if (error) { + psmouse_err(psmouse, + "failed to register secondary device: %d\n", + error); + input_free_device(dev3); + goto out; + } + + priv->dev3 = dev3; + +out: + /* + * Save the error code so that we can detect that we + * already tried to create the device. + */ + if (error) + priv->dev3 = ERR_PTR(error); + + mutex_unlock(&alps_mutex); +} + +static void alps_report_bare_ps2_packet(struct input_dev *dev, unsigned char packet[], bool report_buttons) { - struct alps_data *priv = psmouse->private; - struct input_dev *dev2 = priv->dev2; - if (report_buttons) - alps_report_buttons(psmouse, dev2, psmouse->dev, + alps_report_buttons(dev, NULL, packet[0] & 1, packet[0] & 2, packet[0] & 4); - input_report_rel(dev2, REL_X, + input_report_rel(dev, REL_X, packet[1] ? packet[1] - ((packet[0] << 4) & 0x100) : 0); - input_report_rel(dev2, REL_Y, + input_report_rel(dev, REL_Y, packet[2] ? ((packet[0] << 3) & 0x100) - packet[2] : 0); - input_sync(dev2); + input_sync(dev); } static psmouse_ret_t alps_handle_interleaved_ps2(struct psmouse *psmouse) @@ -1204,8 +1270,8 @@ static psmouse_ret_t alps_handle_interleaved_ps2(struct psmouse *psmouse) * de-synchronization. */ - alps_report_bare_ps2_packet(psmouse, &psmouse->packet[3], - false); + alps_report_bare_ps2_packet(priv->dev2, + &psmouse->packet[3], false); /* * Continue with the standard ALPS protocol handling, @@ -1261,9 +1327,18 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse) * properly we only do this if the device is fully synchronized. */ if (!psmouse->out_of_sync_cnt && (psmouse->packet[0] & 0xc8) == 0x08) { + + /* Register dev3 mouse if we received PS/2 packet first time */ + if (unlikely(!priv->dev3)) + psmouse_queue_work(psmouse, + &priv->dev3_register_work, 0); + if (psmouse->pktcnt == 3) { - alps_report_bare_ps2_packet(psmouse, psmouse->packet, - true); + /* Once dev3 mouse device is registered report data */ + if (likely(!IS_ERR_OR_NULL(priv->dev3))) + alps_report_bare_ps2_packet(priv->dev3, + psmouse->packet, + true); return PSMOUSE_FULL_PACKET; } return PSMOUSE_GOOD_DATA; @@ -2378,7 +2453,10 @@ static void alps_disconnect(struct psmouse *psmouse) psmouse_reset(psmouse); del_timer_sync(&priv->timer); - input_unregister_device(priv->dev2); + if (priv->dev2) + input_unregister_device(priv->dev2); + if (!IS_ERR_OR_NULL(priv->dev3)) + input_unregister_device(priv->dev3); kfree(priv); } @@ -2412,17 +2490,9 @@ static void alps_set_abs_params_mt(struct alps_data *priv, int alps_init(struct psmouse *psmouse) { struct alps_data *priv = psmouse->private; - struct input_dev *dev1 = psmouse->dev, *dev2; + struct input_dev *dev1 = psmouse->dev; int error; - dev2 = input_allocate_device(); - if (!dev2) { - error = -ENOMEM; - goto init_fail; - } - - priv->dev2 = dev2; - error = priv->hw_init(psmouse); if (error) goto init_fail; @@ -2474,36 +2544,57 @@ int alps_init(struct psmouse *psmouse) } if (priv->flags & ALPS_DUALPOINT) { + struct input_dev *dev2; + + dev2 = input_allocate_device(); + if (!dev2) { + psmouse_err(psmouse, + "failed to allocate trackstick device\n"); + error = -ENOMEM; + goto init_fail; + } + + snprintf(priv->phys2, sizeof(priv->phys2), "%s/input1", + psmouse->ps2dev.serio->phys); + dev2->phys = priv->phys2; + /* * format of input device name is: "protocol vendor name" * see function psmouse_switch_protocol() in psmouse-base.c */ dev2->name = "AlpsPS/2 ALPS DualPoint Stick"; + + dev2->id.bustype = BUS_I8042; + dev2->id.vendor = 0x0002; dev2->id.product = PSMOUSE_ALPS; dev2->id.version = priv->proto_version; - } else { - dev2->name = "PS/2 ALPS Mouse"; - dev2->id.product = PSMOUSE_PS2; - dev2->id.version = 0x0000; - } - - snprintf(priv->phys, sizeof(priv->phys), "%s/input1", psmouse->ps2dev.serio->phys); - dev2->phys = priv->phys; - dev2->id.bustype = BUS_I8042; - dev2->id.vendor = 0x0002; - dev2->dev.parent = &psmouse->ps2dev.serio->dev; + dev2->dev.parent = &psmouse->ps2dev.serio->dev; - dev2->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); - dev2->relbit[BIT_WORD(REL_X)] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); - dev2->keybit[BIT_WORD(BTN_LEFT)] = - BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); + input_set_capability(dev2, EV_REL, REL_X); + input_set_capability(dev2, EV_REL, REL_Y); + input_set_capability(dev2, EV_KEY, BTN_LEFT); + input_set_capability(dev2, EV_KEY, BTN_RIGHT); + input_set_capability(dev2, EV_KEY, BTN_MIDDLE); - __set_bit(INPUT_PROP_POINTER, dev2->propbit); - if (priv->flags & ALPS_DUALPOINT) + __set_bit(INPUT_PROP_POINTER, dev2->propbit); __set_bit(INPUT_PROP_POINTING_STICK, dev2->propbit); - if (input_register_device(priv->dev2)) - goto init_fail; + error = input_register_device(dev2); + if (error) { + psmouse_err(psmouse, + "failed to register trackstick device: %d\n", + error); + input_free_device(dev2); + goto init_fail; + } + + priv->dev2 = dev2; + } + + priv->psmouse = psmouse; + + INIT_DELAYED_WORK(&priv->dev3_register_work, + alps_register_bare_ps2_mouse); psmouse->protocol_handler = alps_process_byte; psmouse->poll = alps_poll; @@ -2521,7 +2612,6 @@ int alps_init(struct psmouse *psmouse) init_fail: psmouse_reset(psmouse); - input_free_device(dev2); /* * Even though we did not allocate psmouse->private we do free * it here. diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h index c7952356260..02513c0502f 100644 --- a/drivers/input/mouse/alps.h +++ b/drivers/input/mouse/alps.h @@ -141,8 +141,12 @@ struct alps_fields { /** * struct alps_data - private data structure for the ALPS driver - * @dev2: "Relative" device used to report trackstick or mouse activity. - * @phys: Physical path for the relative device. + * @psmouse: Pointer to parent psmouse device + * @dev2: Trackstick device (can be NULL). + * @dev3: Generic PS/2 mouse (can be NULL, delayed registering). + * @phys2: Physical path for the trackstick device. + * @phys3: Physical path for the generic PS/2 mouse. + * @dev3_register_work: Delayed work for registering PS/2 mouse. * @nibble_commands: Command mapping used for touchpad register accesses. * @addr_command: Command used to tell the touchpad that a register address * follows. @@ -169,8 +173,12 @@ struct alps_fields { * @timer: Timer for flushing out the final report packet in the stream. */ struct alps_data { + struct psmouse *psmouse; struct input_dev *dev2; - char phys[32]; + struct input_dev *dev3; + char phys2[32]; + char phys3[32]; + struct delayed_work dev3_register_work; /* these are autodetected when the device is identified */ const struct alps_nibble_commands *nibble_commands; -- cgit v1.2.3-70-g09d2 From 626b9da0b5a55407ebddcfa9b983180e729736ce Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 15 Feb 2015 15:55:16 -0800 Subject: Input: ALPS - fix confusing comment in protocol data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The comment about suspicions entry 0x20, 0x02, 0x0e has over time drifted away and it become hard to figure out what it meant. Let's move it back so it is clear. Reported-by: Pali Rohár Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/alps.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'drivers/input/mouse') diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index a4d69ef0f84..b4144ad0987 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -117,7 +117,14 @@ static const struct alps_model_info alps_model_data[] = { { { 0x73, 0x00, 0x0a }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_DUALPOINT } }, /* ThinkPad R61 8918-5QG */ { { 0x73, 0x02, 0x0a }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, 0 } }, { { 0x73, 0x02, 0x14 }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_FW_BK_2 } }, /* Ahtec Laptop */ - { { 0x20, 0x02, 0x0e }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT } }, /* XXX */ + + /* + * XXX This entry is suspicious. First byte has zero lower nibble, + * which is what a normal mouse would report. Also, the value 0x0e + * isn't valid per PS/2 spec. + */ + { { 0x20, 0x02, 0x0e }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT } }, + { { 0x22, 0x02, 0x0a }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT } }, { { 0x22, 0x02, 0x14 }, 0x00, { ALPS_PROTO_V2, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT } }, /* Dell Latitude D600 */ /* Dell Latitude E5500, E6400, E6500, Precision M4400 */ @@ -151,12 +158,6 @@ static void alps_set_abs_params_st(struct alps_data *priv, static void alps_set_abs_params_mt(struct alps_data *priv, struct input_dev *dev1); -/* - * XXX - this entry is suspicious. First byte has zero lower nibble, - * which is what a normal mouse would report. Also, the value 0x0e - * isn't valid per PS/2 spec. - */ - /* Packet formats are described in Documentation/input/alps.txt */ static bool alps_is_valid_first_byte(struct alps_data *priv, -- cgit v1.2.3-70-g09d2 From ef47fa5280819deaa8da7e0db1d875b225de5838 Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Sun, 15 Feb 2015 15:58:08 -0800 Subject: Input: ALPS - move v7 packet info to Documentation and v6 packet info MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch move all packet info from driver source code to documentation and adds info about v6 packet format (from driver source code). Signed-off-by: Pali Rohár Acked-by: Hans de Goede Signed-off-by: Dmitry Torokhov --- Documentation/input/alps.txt | 68 ++++++++++++++++++++++++++++++++++++++++++-- drivers/input/mouse/alps.c | 39 ------------------------- 2 files changed, 66 insertions(+), 41 deletions(-) (limited to 'drivers/input/mouse') diff --git a/Documentation/input/alps.txt b/Documentation/input/alps.txt index 90bca6f988e..a63e5e013a8 100644 --- a/Documentation/input/alps.txt +++ b/Documentation/input/alps.txt @@ -3,8 +3,8 @@ ALPS Touchpad Protocol Introduction ------------ -Currently the ALPS touchpad driver supports five protocol versions in use by -ALPS touchpads, called versions 1, 2, 3, 4 and 5. +Currently the ALPS touchpad driver supports seven protocol versions in use by +ALPS touchpads, called versions 1, 2, 3, 4, 5, 6 and 7. Since roughly mid-2010 several new ALPS touchpads have been released and integrated into a variety of laptops and netbooks. These new touchpads @@ -240,3 +240,67 @@ For mt, the format is: byte 3: 0 x23 x22 x21 x20 x19 x18 x17 byte 4: 0 x9 x8 x7 x6 x5 x4 x3 byte 5: 0 x16 x15 x14 x13 x12 x11 x10 + +ALPS Absolute Mode - Protocol Version 6 +--------------------------------------- + +For trackstick packet, the format is: + + byte 0: 1 1 1 1 1 1 1 1 + byte 1: 0 X6 X5 X4 X3 X2 X1 X0 + byte 2: 0 Y6 Y5 Y4 Y3 Y2 Y1 Y0 + byte 3: ? Y7 X7 ? ? M R L + byte 4: Z7 Z6 Z5 Z4 Z3 Z2 Z1 Z0 + byte 5: 0 1 1 1 1 1 1 1 + +For touchpad packet, the format is: + + byte 0: 1 1 1 1 1 1 1 1 + byte 1: 0 0 0 0 x3 x2 x1 x0 + byte 2: 0 0 0 0 y3 y2 y1 y0 + byte 3: ? x7 x6 x5 x4 ? r l + byte 4: ? y7 y6 y5 y4 ? ? ? + byte 5: z7 z6 z5 z4 z3 z2 z1 z0 + +(v6 touchpad does not have middle button) + +ALPS Absolute Mode - Protocol Version 7 +--------------------------------------- + +For trackstick packet, the format is: + + byte 0: 0 1 0 0 1 0 0 0 + byte 1: 1 1 * * 1 M R L + byte 2: X7 1 X5 X4 X3 X2 X1 X0 + byte 3: Z6 1 Y6 X6 1 Y2 Y1 Y0 + byte 4: Y7 0 Y5 Y4 Y3 1 1 0 + byte 5: T&P 0 Z5 Z4 Z3 Z2 Z1 Z0 + +For touchpad packet, the format is: + + packet-fmt b7 b6 b5 b4 b3 b2 b1 b0 + byte 0: TWO & MULTI L 1 R M 1 Y0-2 Y0-1 Y0-0 + byte 0: NEW L 1 X1-5 1 1 Y0-2 Y0-1 Y0-0 + byte 1: Y0-10 Y0-9 Y0-8 Y0-7 Y0-6 Y0-5 Y0-4 Y0-3 + byte 2: X0-11 1 X0-10 X0-9 X0-8 X0-7 X0-6 X0-5 + byte 3: X1-11 1 X0-4 X0-3 1 X0-2 X0-1 X0-0 + byte 4: TWO X1-10 TWO X1-9 X1-8 X1-7 X1-6 X1-5 X1-4 + byte 4: MULTI X1-10 TWO X1-9 X1-8 X1-7 X1-6 Y1-5 1 + byte 4: NEW X1-10 TWO X1-9 X1-8 X1-7 X1-6 0 0 + byte 5: TWO & NEW Y1-10 0 Y1-9 Y1-8 Y1-7 Y1-6 Y1-5 Y1-4 + byte 5: MULTI Y1-10 0 Y1-9 Y1-8 Y1-7 Y1-6 F-1 F-0 + + L: Left button + R / M: Non-clickpads: Right / Middle button + Clickpads: When > 2 fingers are down, and some fingers + are in the button area, then the 2 coordinates reported + are for fingers outside the button area and these report + extra fingers being present in the right / left button + area. Note these fingers are not added to the F field! + so if a TWO packet is received and R = 1 then there are + 3 fingers down, etc. + TWO: 1: Two touches present, byte 0/4/5 are in TWO fmt + 0: If byte 4 bit 0 is 1, then byte 0/4/5 are in MULTI fmt + otherwise byte 0 bit 4 must be set and byte 0/4/5 are + in NEW fmt + F: Number of fingers - 3, 0 means 3 fingers, 1 means 4 ... diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index b4144ad0987..d28726a0ef8 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -909,34 +909,6 @@ static void alps_get_finger_coordinate_v7(struct input_mt_pos *mt, unsigned char *pkt, unsigned char pkt_id) { - /* - * packet-fmt b7 b6 b5 b4 b3 b2 b1 b0 - * Byte0 TWO & MULTI L 1 R M 1 Y0-2 Y0-1 Y0-0 - * Byte0 NEW L 1 X1-5 1 1 Y0-2 Y0-1 Y0-0 - * Byte1 Y0-10 Y0-9 Y0-8 Y0-7 Y0-6 Y0-5 Y0-4 Y0-3 - * Byte2 X0-11 1 X0-10 X0-9 X0-8 X0-7 X0-6 X0-5 - * Byte3 X1-11 1 X0-4 X0-3 1 X0-2 X0-1 X0-0 - * Byte4 TWO X1-10 TWO X1-9 X1-8 X1-7 X1-6 X1-5 X1-4 - * Byte4 MULTI X1-10 TWO X1-9 X1-8 X1-7 X1-6 Y1-5 1 - * Byte4 NEW X1-10 TWO X1-9 X1-8 X1-7 X1-6 0 0 - * Byte5 TWO & NEW Y1-10 0 Y1-9 Y1-8 Y1-7 Y1-6 Y1-5 Y1-4 - * Byte5 MULTI Y1-10 0 Y1-9 Y1-8 Y1-7 Y1-6 F-1 F-0 - * L: Left button - * R / M: Non-clickpads: Right / Middle button - * Clickpads: When > 2 fingers are down, and some fingers - * are in the button area, then the 2 coordinates reported - * are for fingers outside the button area and these report - * extra fingers being present in the right / left button - * area. Note these fingers are not added to the F field! - * so if a TWO packet is received and R = 1 then there are - * 3 fingers down, etc. - * TWO: 1: Two touches present, byte 0/4/5 are in TWO fmt - * 0: If byte 4 bit 0 is 1, then byte 0/4/5 are in MULTI fmt - * otherwise byte 0 bit 4 must be set and byte 0/4/5 are - * in NEW fmt - * F: Number of fingers - 3, 0 means 3 fingers, 1 means 4 ... - */ - mt[0].x = ((pkt[2] & 0x80) << 4); mt[0].x |= ((pkt[2] & 0x3F) << 5); mt[0].x |= ((pkt[3] & 0x30) >> 1); @@ -1061,17 +1033,6 @@ static void alps_process_trackstick_packet_v7(struct psmouse *psmouse) return; } - /* - * b7 b6 b5 b4 b3 b2 b1 b0 - * Byte0 0 1 0 0 1 0 0 0 - * Byte1 1 1 * * 1 M R L - * Byte2 X7 1 X5 X4 X3 X2 X1 X0 - * Byte3 Z6 1 Y6 X6 1 Y2 Y1 Y0 - * Byte4 Y7 0 Y5 Y4 Y3 1 1 0 - * Byte5 T&P 0 Z5 Z4 Z3 Z2 Z1 Z0 - * M / R / L: Middle / Right / Left button - */ - x = ((packet[2] & 0xbf)) | ((packet[3] & 0x10) << 2); y = (packet[3] & 0x07) | (packet[4] & 0xb8) | ((packet[3] & 0x20) << 1); -- cgit v1.2.3-70-g09d2 From 290b799c390d77d27effee3ce312203aaa32ee74 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 29 Dec 2014 12:06:38 -0800 Subject: Input: psmouse - use IS_ENABLED instead of homegrown code Instead of having various protocols provide _supported() functions, let's use IS_ENABLED() macro that works well in "if" statements. Acked-by: Hans de Goede Reviewed-by: Benjamin Tissoires Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/cypress_ps2.c | 5 ----- drivers/input/mouse/cypress_ps2.h | 5 ----- drivers/input/mouse/focaltech.c | 10 ---------- drivers/input/mouse/focaltech.h | 1 - drivers/input/mouse/psmouse-base.c | 6 +++--- drivers/input/mouse/synaptics.c | 10 ---------- drivers/input/mouse/synaptics.h | 1 - 7 files changed, 3 insertions(+), 35 deletions(-) (limited to 'drivers/input/mouse') diff --git a/drivers/input/mouse/cypress_ps2.c b/drivers/input/mouse/cypress_ps2.c index 9118a1861a4..28dcfc822bf 100644 --- a/drivers/input/mouse/cypress_ps2.c +++ b/drivers/input/mouse/cypress_ps2.c @@ -710,8 +710,3 @@ err_exit: return -1; } - -bool cypress_supported(void) -{ - return true; -} diff --git a/drivers/input/mouse/cypress_ps2.h b/drivers/input/mouse/cypress_ps2.h index 4720f21d2d7..81f68aaed7c 100644 --- a/drivers/input/mouse/cypress_ps2.h +++ b/drivers/input/mouse/cypress_ps2.h @@ -172,7 +172,6 @@ struct cytp_data { #ifdef CONFIG_MOUSE_PS2_CYPRESS int cypress_detect(struct psmouse *psmouse, bool set_properties); int cypress_init(struct psmouse *psmouse); -bool cypress_supported(void); #else inline int cypress_detect(struct psmouse *psmouse, bool set_properties) { @@ -182,10 +181,6 @@ inline int cypress_init(struct psmouse *psmouse) { return -ENOSYS; } -inline bool cypress_supported(void) -{ - return 0; -} #endif /* CONFIG_MOUSE_PS2_CYPRESS */ #endif /* _CYPRESS_PS2_H */ diff --git a/drivers/input/mouse/focaltech.c b/drivers/input/mouse/focaltech.c index fca38ba63bb..757f78a94ae 100644 --- a/drivers/input/mouse/focaltech.c +++ b/drivers/input/mouse/focaltech.c @@ -424,11 +424,6 @@ fail: return error; } -bool focaltech_supported(void) -{ - return true; -} - #else /* CONFIG_MOUSE_PS2_FOCALTECH */ int focaltech_init(struct psmouse *psmouse) @@ -438,9 +433,4 @@ int focaltech_init(struct psmouse *psmouse) return 0; } -bool focaltech_supported(void) -{ - return false; -} - #endif /* CONFIG_MOUSE_PS2_FOCALTECH */ diff --git a/drivers/input/mouse/focaltech.h b/drivers/input/mouse/focaltech.h index 71870a9b548..ca61ebff373 100644 --- a/drivers/input/mouse/focaltech.h +++ b/drivers/input/mouse/focaltech.h @@ -19,6 +19,5 @@ int focaltech_detect(struct psmouse *psmouse, bool set_properties); int focaltech_init(struct psmouse *psmouse); -bool focaltech_supported(void); #endif diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 68469feda47..4ccd01d7a48 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -727,7 +727,7 @@ static int psmouse_extensions(struct psmouse *psmouse, if (psmouse_do_detect(focaltech_detect, psmouse, set_properties) == 0) { if (max_proto > PSMOUSE_IMEX) { if (!set_properties || focaltech_init(psmouse) == 0) { - if (focaltech_supported()) + if (IS_ENABLED(CONFIG_MOUSE_PS2_FOCALTECH)) return PSMOUSE_FOCALTECH; /* * Note that we need to also restrict @@ -776,7 +776,7 @@ static int psmouse_extensions(struct psmouse *psmouse, * Try activating protocol, but check if support is enabled first, since * we try detecting Synaptics even when protocol is disabled. */ - if (synaptics_supported() && + if (IS_ENABLED(CONFIG_MOUSE_PS2_SYNAPTICS) && (!set_properties || synaptics_init(psmouse) == 0)) { return PSMOUSE_SYNAPTICS; } @@ -801,7 +801,7 @@ static int psmouse_extensions(struct psmouse *psmouse, */ if (max_proto > PSMOUSE_IMEX && cypress_detect(psmouse, set_properties) == 0) { - if (cypress_supported()) { + if (IS_ENABLED(CONFIG_MOUSE_PS2_CYPRESS)) { if (cypress_init(psmouse) == 0) return PSMOUSE_CYPRESS; diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 7e705ee90b8..f2cceb6493a 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -1454,11 +1454,6 @@ int synaptics_init_relative(struct psmouse *psmouse) return __synaptics_init(psmouse, false); } -bool synaptics_supported(void) -{ - return true; -} - #else /* CONFIG_MOUSE_PS2_SYNAPTICS */ void __init synaptics_module_init(void) @@ -1470,9 +1465,4 @@ int synaptics_init(struct psmouse *psmouse) return -ENOSYS; } -bool synaptics_supported(void) -{ - return false; -} - #endif /* CONFIG_MOUSE_PS2_SYNAPTICS */ diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h index 6faf9bb7c11..aedc3299b14 100644 --- a/drivers/input/mouse/synaptics.h +++ b/drivers/input/mouse/synaptics.h @@ -175,6 +175,5 @@ int synaptics_detect(struct psmouse *psmouse, bool set_properties); int synaptics_init(struct psmouse *psmouse); int synaptics_init_relative(struct psmouse *psmouse); void synaptics_reset(struct psmouse *psmouse); -bool synaptics_supported(void); #endif /* _SYNAPTICS_H */ -- cgit v1.2.3-70-g09d2