Lines Matching +full:middle +full:- +full:button
1 // SPDX-License-Identifier: GPL-2.0-only
6 * Added support for pass-through port. Special thanks to Peter Berg Larsen
13 * start merging tpconfig and gpm code to a xfree-input module
14 * adding some changes and extensions (ex. 3rd and 4th button)
17 * Copyright (c) 1998-2000 Bruce Kalk <kall@compass.com>
18 * code for the special synaptics commands (from the tpconfig-source)
61 * value which are actually negative values truncated to the 13-bit
63 * than 8184 (i.e. -8), so we treat all values greater than 8176 as
84 error = ps2_sliced_command(&psmouse->ps2dev, mode); in synaptics_mode_cmd()
89 error = ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_SETRATE); in synaptics_mode_cmd()
98 struct ps2dev *ps2dev = &psmouse->ps2dev; in synaptics_detect()
108 return -ENODEV; in synaptics_detect()
111 psmouse->vendor = "Synaptics"; in synaptics_detect()
112 psmouse->name = "TouchPad"; in synaptics_detect()
178 "LEN0072", /* X1 Carbon Gen 5 (2017) - Elan/ALPS trackpoint */
184 "LEN0097", /* X280 -> ALPS trackpoint */
200 "SYN3221", /* HP 15-ay000 */
201 "SYN323d", /* HP Spectre X360 13-w013dx */
202 "SYN3257", /* HP Envy 13-ad105ng */
203 "TOS01f6", /* Dynabook Portege X30L-G */
204 "TOS0213", /* Dynabook Portege X30-D */
222 error = ps2_sliced_command(&psmouse->ps2dev, cmd); in synaptics_send_cmd()
226 error = ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_GETINFO); in synaptics_send_cmd()
258 error = synaptics_query_int(psmouse, SYN_QUE_IDENTIFY, &info->identity); in synaptics_identify()
262 return SYN_ID_IS_SYNAPTICS(info->identity) ? 0 : -ENXIO; in synaptics_identify()
266 * Read the model-id bytes from the touchpad
272 return synaptics_query_int(psmouse, SYN_QUE_MODEL, &info->model_id); in synaptics_model_id()
282 &info->firmware_id); in synaptics_firmware_id()
296 if (SYN_ID_FULL(info->identity) < 0x705) in synaptics_query_modes()
303 info->board_id = ((bid[0] & 0xfc) << 6) | bid[1]; in synaptics_query_modes()
307 &info->ext_cap_10); in synaptics_query_modes()
313 * Read the capability-bits from the touchpad
322 &info->capabilities); in synaptics_capability()
326 info->ext_cap = info->ext_cap_0c = 0; in synaptics_capability()
331 if (SYN_ID_FULL(info->identity) < 0x705 && in synaptics_capability()
332 SYN_CAP_SUBMODEL_ID(info->capabilities) != 0x47) { in synaptics_capability()
333 return -ENXIO; in synaptics_capability()
339 if (!SYN_CAP_EXTENDED(info->capabilities)) in synaptics_capability()
340 info->capabilities = 0; in synaptics_capability()
342 if (SYN_EXT_CAP_REQUESTS(info->capabilities) >= 1) { in synaptics_capability()
344 &info->ext_cap); in synaptics_capability()
353 if (SYN_CAP_MULTI_BUTTON_NO(info->ext_cap) > 8) in synaptics_capability()
354 info->ext_cap &= ~SYN_CAP_MB_MASK; in synaptics_capability()
358 if (SYN_EXT_CAP_REQUESTS(info->capabilities) >= 4) { in synaptics_capability()
360 &info->ext_cap_0c); in synaptics_capability()
379 if (SYN_ID_MAJOR(info->identity) < 4) in synaptics_resolution()
385 info->x_res = resp[0]; /* x resolution in units/mm */ in synaptics_resolution()
386 info->y_res = resp[2]; /* y resolution in units/mm */ in synaptics_resolution()
390 if (SYN_EXT_CAP_REQUESTS(info->capabilities) >= 5 && in synaptics_resolution()
391 SYN_CAP_MAX_DIMENSIONS(info->ext_cap_0c)) { in synaptics_resolution()
398 info->x_max = (resp[0] << 5) | ((resp[1] & 0x0f) << 1); in synaptics_resolution()
399 info->y_max = (resp[2] << 5) | ((resp[1] & 0xf0) >> 3); in synaptics_resolution()
402 info->x_max, info->y_max); in synaptics_resolution()
406 if (SYN_CAP_MIN_DIMENSIONS(info->ext_cap_0c) && in synaptics_resolution()
407 (SYN_EXT_CAP_REQUESTS(info->capabilities) >= 7 || in synaptics_resolution()
413 SYN_ID_FULL(info->identity) == 0x801)) { in synaptics_resolution()
420 info->x_min = (resp[0] << 5) | ((resp[1] & 0x0f) << 1); in synaptics_resolution()
421 info->y_min = (resp[2] << 5) | ((resp[1] & 0xf0) >> 3); in synaptics_resolution()
424 info->x_min, info->y_min); in synaptics_resolution()
532 return YMAX_NOMINAL + YMIN_NOMINAL - y; in synaptics_invert_y()
549 info->board_id < min_max_pnpid_table[i].board_id.min) in synaptics_apply_quirks()
553 info->board_id > min_max_pnpid_table[i].board_id.max) in synaptics_apply_quirks()
556 info->x_min = min_max_pnpid_table[i].x_min; in synaptics_apply_quirks()
557 info->x_max = min_max_pnpid_table[i].x_max; in synaptics_apply_quirks()
558 info->y_min = min_max_pnpid_table[i].y_min; in synaptics_apply_quirks()
559 info->y_max = min_max_pnpid_table[i].y_max; in synaptics_apply_quirks()
562 info->x_min, info->x_max, in synaptics_apply_quirks()
563 info->y_min, info->y_max); in synaptics_apply_quirks()
570 return (SYN_CAP_ADV_GESTURE(priv->info.ext_cap_0c) || in synaptics_has_agm()
571 SYN_CAP_IMAGE_SENSOR(priv->info.ext_cap_0c)); in synaptics_has_agm()
579 error = ps2_sliced_command(&psmouse->ps2dev, SYN_QUE_MODEL); in synaptics_set_advanced_gesture_mode()
583 error = ps2_command(&psmouse->ps2dev, ¶m, PSMOUSE_CMD_SETRATE); in synaptics_set_advanced_gesture_mode()
592 struct synaptics_data *priv = psmouse->private; in synaptics_set_mode()
595 priv->mode = 0; in synaptics_set_mode()
596 if (priv->absolute_mode) in synaptics_set_mode()
597 priv->mode |= SYN_BIT_ABSOLUTE_MODE; in synaptics_set_mode()
598 if (priv->disable_gesture) in synaptics_set_mode()
599 priv->mode |= SYN_BIT_DISABLE_GESTURE; in synaptics_set_mode()
600 if (psmouse->rate >= 80) in synaptics_set_mode()
601 priv->mode |= SYN_BIT_HIGH_RATE; in synaptics_set_mode()
602 if (SYN_CAP_EXTENDED(priv->info.capabilities)) in synaptics_set_mode()
603 priv->mode |= SYN_BIT_W_MODE; in synaptics_set_mode()
605 error = synaptics_mode_cmd(psmouse, priv->mode); in synaptics_set_mode()
609 if (priv->absolute_mode && synaptics_has_agm(priv)) { in synaptics_set_mode()
624 struct synaptics_data *priv = psmouse->private; in synaptics_set_rate()
627 priv->mode |= SYN_BIT_HIGH_RATE; in synaptics_set_rate()
628 psmouse->rate = 80; in synaptics_set_rate()
630 priv->mode &= ~SYN_BIT_HIGH_RATE; in synaptics_set_rate()
631 psmouse->rate = 40; in synaptics_set_rate()
634 synaptics_mode_cmd(psmouse, priv->mode); in synaptics_set_rate()
638 * Synaptics pass-through PS/2 port support
642 struct psmouse *parent = psmouse_from_serio(serio->parent); in synaptics_pt_write()
643 u8 rate_param = SYN_PS_CLIENT_CMD; /* indicates that we want pass-through port */ in synaptics_pt_write()
646 error = ps2_sliced_command(&parent->ps2dev, c); in synaptics_pt_write()
650 error = ps2_command(&parent->ps2dev, &rate_param, PSMOUSE_CMD_SETRATE); in synaptics_pt_write()
659 struct psmouse *parent = psmouse_from_serio(serio->parent); in synaptics_pt_start()
660 struct synaptics_data *priv = parent->private; in synaptics_pt_start()
662 guard(serio_pause_rx)(parent->ps2dev.serio); in synaptics_pt_start()
663 priv->pt_port = serio; in synaptics_pt_start()
670 struct psmouse *parent = psmouse_from_serio(serio->parent); in synaptics_pt_stop()
671 struct synaptics_data *priv = parent->private; in synaptics_pt_stop()
673 guard(serio_pause_rx)(parent->ps2dev.serio); in synaptics_pt_stop()
674 priv->pt_port = NULL; in synaptics_pt_stop()
679 struct psmouse *parent = psmouse_from_serio(serio->parent); in synaptics_pt_open()
680 struct synaptics_data *priv = parent->private; in synaptics_pt_open()
682 guard(serio_pause_rx)(parent->ps2dev.serio); in synaptics_pt_open()
683 priv->pt_port_open = true; in synaptics_pt_open()
690 struct psmouse *parent = psmouse_from_serio(serio->parent); in synaptics_pt_close()
691 struct synaptics_data *priv = parent->private; in synaptics_pt_close()
693 guard(serio_pause_rx)(parent->ps2dev.serio); in synaptics_pt_close()
694 priv->pt_port_open = false; in synaptics_pt_close()
706 ptport = priv->pt_port; in synaptics_pass_pt_packet()
712 if (priv->pt_port_open) { in synaptics_pass_pt_packet()
715 if (child->state == PSMOUSE_ACTIVATED) { in synaptics_pass_pt_packet()
718 if (child->pktsize == 4) in synaptics_pass_pt_packet()
726 struct synaptics_data *priv = psmouse->private; in synaptics_pt_activate()
727 struct psmouse *child = psmouse_from_serio(priv->pt_port); in synaptics_pt_activate()
731 if (child->pktsize == 4) in synaptics_pt_activate()
732 priv->mode |= SYN_BIT_FOUR_BYTE_CLIENT; in synaptics_pt_activate()
734 priv->mode &= ~SYN_BIT_FOUR_BYTE_CLIENT; in synaptics_pt_activate()
736 if (synaptics_mode_cmd(psmouse, priv->mode)) in synaptics_pt_activate()
749 "not enough memory for pass-through port\n"); in synaptics_pt_create()
753 serio->id.type = SERIO_PS_PSTHRU; in synaptics_pt_create()
754 strscpy(serio->name, "Synaptics pass-through", sizeof(serio->name)); in synaptics_pt_create()
755 strscpy(serio->phys, "synaptics-pt/serio0", sizeof(serio->phys)); in synaptics_pt_create()
756 serio->write = synaptics_pt_write; in synaptics_pt_create()
757 serio->start = synaptics_pt_start; in synaptics_pt_create()
758 serio->stop = synaptics_pt_stop; in synaptics_pt_create()
759 serio->open = synaptics_pt_open; in synaptics_pt_create()
760 serio->close = synaptics_pt_close; in synaptics_pt_create()
761 serio->parent = psmouse->ps2dev.serio; in synaptics_pt_create()
763 psmouse->pt_activate = synaptics_pt_activate; in synaptics_pt_create()
766 serio->name, psmouse->phys); in synaptics_pt_create()
778 struct synaptics_hw_state *agm = &priv->agm; in synaptics_parse_agm()
785 agm->w = hw->w; in synaptics_parse_agm()
786 agm->x = (((buf[4] & 0x0f) << 8) | buf[1]) << 1; in synaptics_parse_agm()
787 agm->y = (((buf[4] & 0xf0) << 4) | buf[2]) << 1; in synaptics_parse_agm()
788 agm->z = ((buf[3] & 0x30) | (buf[5] & 0x0f)) << 1; in synaptics_parse_agm()
792 /* AGM-CONTACT packet: we are only interested in the count */ in synaptics_parse_agm()
793 priv->agm_count = buf[1]; in synaptics_parse_agm()
806 (SYN_CAP_MULTI_BUTTON_NO(priv->info.ext_cap) + 1) >> 1; in synaptics_parse_ext_buttons()
807 unsigned int ext_mask = GENMASK(ext_bits - 1, 0); in synaptics_parse_ext_buttons()
809 hw->ext_buttons = buf[4] & ext_mask; in synaptics_parse_ext_buttons()
810 hw->ext_buttons |= (buf[5] & ext_mask) << ext_bits; in synaptics_parse_ext_buttons()
819 if (SYN_MODEL_NEWABS(priv->info.model_id)) { in synaptics_parse_hw_state()
820 hw->w = (((buf[0] & 0x30) >> 2) | in synaptics_parse_hw_state()
824 if (synaptics_has_agm(priv) && hw->w == 2) { in synaptics_parse_hw_state()
829 hw->x = (((buf[3] & 0x10) << 8) | in synaptics_parse_hw_state()
832 hw->y = (((buf[3] & 0x20) << 7) | in synaptics_parse_hw_state()
835 hw->z = buf[2]; in synaptics_parse_hw_state()
837 hw->left = (buf[0] & 0x01) ? 1 : 0; in synaptics_parse_hw_state()
838 hw->right = (buf[0] & 0x02) ? 1 : 0; in synaptics_parse_hw_state()
840 if (priv->is_forcepad) { in synaptics_parse_hw_state()
842 * ForcePads, like Clickpads, use middle button in synaptics_parse_hw_state()
843 * bits to report primary button clicks. in synaptics_parse_hw_state()
844 * Unfortunately they report primary button not in synaptics_parse_hw_state()
848 * out multi-finger gestures. in synaptics_parse_hw_state()
850 if (hw->z == 0) { in synaptics_parse_hw_state()
852 priv->press = priv->report_press = false; in synaptics_parse_hw_state()
853 } else if (hw->w >= 4 && ((buf[0] ^ buf[3]) & 0x01)) { in synaptics_parse_hw_state()
855 * Single-finger touch with pressure above in synaptics_parse_hw_state()
858 * button. We rely on the device continuing in synaptics_parse_hw_state()
862 if (!priv->press) { in synaptics_parse_hw_state()
863 priv->press_start = jiffies; in synaptics_parse_hw_state()
864 priv->press = true; in synaptics_parse_hw_state()
866 priv->press_start + in synaptics_parse_hw_state()
868 priv->report_press = true; in synaptics_parse_hw_state()
871 priv->press = false; in synaptics_parse_hw_state()
874 hw->left = priv->report_press; in synaptics_parse_hw_state()
876 } else if (SYN_CAP_CLICKPAD(priv->info.ext_cap_0c)) { in synaptics_parse_hw_state()
878 * Clickpad's button is transmitted as middle button, in synaptics_parse_hw_state()
879 * however, since it is primary button, we will report in synaptics_parse_hw_state()
882 hw->left = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0; in synaptics_parse_hw_state()
884 } else if (SYN_CAP_MIDDLE_BUTTON(priv->info.capabilities)) { in synaptics_parse_hw_state()
885 hw->middle = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0; in synaptics_parse_hw_state()
886 if (hw->w == 2) in synaptics_parse_hw_state()
887 hw->scroll = (s8)buf[1]; in synaptics_parse_hw_state()
890 if (SYN_CAP_FOUR_BUTTON(priv->info.capabilities)) { in synaptics_parse_hw_state()
891 hw->up = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0; in synaptics_parse_hw_state()
892 hw->down = ((buf[0] ^ buf[3]) & 0x02) ? 1 : 0; in synaptics_parse_hw_state()
895 if (SYN_CAP_MULTI_BUTTON_NO(priv->info.ext_cap) > 0 && in synaptics_parse_hw_state()
900 hw->x = (((buf[1] & 0x1f) << 8) | buf[2]); in synaptics_parse_hw_state()
901 hw->y = (((buf[4] & 0x1f) << 8) | buf[5]); in synaptics_parse_hw_state()
903 hw->z = (((buf[0] & 0x30) << 2) | (buf[3] & 0x3F)); in synaptics_parse_hw_state()
904 hw->w = (((buf[1] & 0x80) >> 4) | ((buf[0] & 0x04) >> 1)); in synaptics_parse_hw_state()
906 hw->left = (buf[0] & 0x01) ? 1 : 0; in synaptics_parse_hw_state()
907 hw->right = (buf[0] & 0x02) ? 1 : 0; in synaptics_parse_hw_state()
911 * Convert wrap-around values to negative. (X|Y)_MAX_POSITIVE in synaptics_parse_hw_state()
916 if (hw->x > X_MAX_POSITIVE) in synaptics_parse_hw_state()
917 hw->x -= 1 << ABS_POS_BITS; in synaptics_parse_hw_state()
918 else if (hw->x == X_MAX_POSITIVE) in synaptics_parse_hw_state()
919 hw->x = XMAX; in synaptics_parse_hw_state()
921 if (hw->y > Y_MAX_POSITIVE) in synaptics_parse_hw_state()
922 hw->y -= 1 << ABS_POS_BITS; in synaptics_parse_hw_state()
923 else if (hw->y == Y_MAX_POSITIVE) in synaptics_parse_hw_state()
924 hw->y = YMAX; in synaptics_parse_hw_state()
946 synaptics_report_semi_mt_slot(dev, 0, true, min(a->x, b->x), in synaptics_report_semi_mt_data()
947 min(a->y, b->y)); in synaptics_report_semi_mt_data()
948 synaptics_report_semi_mt_slot(dev, 1, true, max(a->x, b->x), in synaptics_report_semi_mt_data()
949 max(a->y, b->y)); in synaptics_report_semi_mt_data()
951 synaptics_report_semi_mt_slot(dev, 0, true, a->x, a->y); in synaptics_report_semi_mt_data()
962 struct input_dev *dev = psmouse->dev; in synaptics_report_ext_buttons()
963 struct synaptics_data *priv = psmouse->private; in synaptics_report_ext_buttons()
964 int ext_bits = (SYN_CAP_MULTI_BUTTON_NO(priv->info.ext_cap) + 1) >> 1; in synaptics_report_ext_buttons()
967 if (!SYN_CAP_MULTI_BUTTON_NO(priv->info.ext_cap)) in synaptics_report_ext_buttons()
971 if ((SYN_ID_FULL(priv->info.identity) == 0x801 || in synaptics_report_ext_buttons()
972 SYN_ID_FULL(priv->info.identity) == 0x802) && in synaptics_report_ext_buttons()
973 !((psmouse->packet[0] ^ psmouse->packet[3]) & 0x02)) in synaptics_report_ext_buttons()
976 if (!SYN_CAP_EXT_BUTTONS_STICK(priv->info.ext_cap_10)) { in synaptics_report_ext_buttons()
979 hw->ext_buttons & BIT(i)); in synaptics_report_ext_buttons()
981 hw->ext_buttons & BIT(i + ext_bits)); in synaptics_report_ext_buttons()
988 * physically wired to the touchpad. Re-route them through in synaptics_report_ext_buttons()
989 * the pass-through interface. in synaptics_report_ext_buttons()
991 if (priv->pt_port) { in synaptics_report_ext_buttons()
995 pt_buttons = SYN_EXT_BUTTON_STICK_L(hw->ext_buttons) | in synaptics_report_ext_buttons()
996 SYN_EXT_BUTTON_STICK_R(hw->ext_buttons) << 1 | in synaptics_report_ext_buttons()
997 SYN_EXT_BUTTON_STICK_M(hw->ext_buttons) << 2; in synaptics_report_ext_buttons()
999 serio_interrupt(priv->pt_port, in synaptics_report_ext_buttons()
1001 serio_interrupt(priv->pt_port, pt_buttons, SERIO_OOB_DATA); in synaptics_report_ext_buttons()
1008 struct input_dev *dev = psmouse->dev; in synaptics_report_buttons()
1009 struct synaptics_data *priv = psmouse->private; in synaptics_report_buttons()
1011 input_report_key(dev, BTN_LEFT, hw->left); in synaptics_report_buttons()
1012 input_report_key(dev, BTN_RIGHT, hw->right); in synaptics_report_buttons()
1014 if (SYN_CAP_MIDDLE_BUTTON(priv->info.capabilities)) in synaptics_report_buttons()
1015 input_report_key(dev, BTN_MIDDLE, hw->middle); in synaptics_report_buttons()
1017 if (SYN_CAP_FOUR_BUTTON(priv->info.capabilities)) { in synaptics_report_buttons()
1018 input_report_key(dev, BTN_FORWARD, hw->up); in synaptics_report_buttons()
1019 input_report_key(dev, BTN_BACK, hw->down); in synaptics_report_buttons()
1029 struct input_dev *dev = psmouse->dev; in synaptics_report_mt_data()
1030 struct synaptics_data *priv = psmouse->private; in synaptics_report_mt_data()
1031 const struct synaptics_hw_state *hw[2] = { sgm, &priv->agm }; in synaptics_report_mt_data()
1038 pos[i].x = hw[i]->x; in synaptics_report_mt_data()
1039 pos[i].y = synaptics_invert_y(hw[i]->y); in synaptics_report_mt_data()
1042 input_mt_assign_slots(dev, slot, pos, nsemi, DMAX * priv->info.x_res); in synaptics_report_mt_data()
1049 input_report_abs(dev, ABS_MT_PRESSURE, hw[i]->z); in synaptics_report_mt_data()
1068 struct synaptics_data *priv = psmouse->private; in synaptics_image_sensor_process()
1074 if (sgm->z == 0) in synaptics_image_sensor_process()
1076 else if (sgm->w >= 4) in synaptics_image_sensor_process()
1078 else if (sgm->w == 0) in synaptics_image_sensor_process()
1080 else if (sgm->w == 1) in synaptics_image_sensor_process()
1081 num_fingers = priv->agm_count ? priv->agm_count : 3; in synaptics_image_sensor_process()
1091 if (SYN_CAP_MULTIFINGER(priv->info.capabilities)) in synaptics_has_multifinger()
1103 struct input_dev *dev = psmouse->dev; in synaptics_process_packet()
1104 struct synaptics_data *priv = psmouse->private; in synaptics_process_packet()
1105 struct synaptics_device_info *info = &priv->info; in synaptics_process_packet()
1110 if (synaptics_parse_hw_state(psmouse->packet, priv, &hw)) in synaptics_process_packet()
1113 if (SYN_CAP_IMAGE_SENSOR(info->ext_cap_0c)) { in synaptics_process_packet()
1119 priv->scroll += hw.scroll; in synaptics_process_packet()
1121 while (priv->scroll >= 4) { in synaptics_process_packet()
1126 priv->scroll -= 4; in synaptics_process_packet()
1128 while (priv->scroll <= -4) { in synaptics_process_packet()
1133 priv->scroll += 4; in synaptics_process_packet()
1141 if (SYN_CAP_EXTENDED(info->capabilities)) { in synaptics_process_packet()
1149 * SYN_MODEL_PEN(info->model_id): even if in synaptics_process_packet()
1155 if (SYN_CAP_PALMDETECT(info->capabilities)) in synaptics_process_packet()
1170 if (SYN_CAP_ADV_GESTURE(info->ext_cap_0c)) in synaptics_process_packet()
1171 synaptics_report_semi_mt_data(dev, &hw, &priv->agm, in synaptics_process_packet()
1176 * absolute -> relative conversion in synaptics_process_packet()
1187 if (SYN_CAP_PALMDETECT(info->capabilities)) in synaptics_process_packet()
1209 const u8 *packet = psmouse->packet; in synaptics_validate_byte()
1249 struct synaptics_data *priv = psmouse->private; in synaptics_process_byte()
1251 if (psmouse->pktcnt >= 6) { /* Full packet received */ in synaptics_process_byte()
1252 if (unlikely(priv->pkt_type == SYN_NEWABS)) in synaptics_process_byte()
1253 priv->pkt_type = synaptics_detect_pkt_type(psmouse); in synaptics_process_byte()
1255 if (SYN_CAP_PASS_THROUGH(priv->info.capabilities) && in synaptics_process_byte()
1256 synaptics_is_pt_packet(psmouse->packet)) { in synaptics_process_byte()
1257 synaptics_pass_pt_packet(priv, psmouse->packet); in synaptics_process_byte()
1265 return synaptics_validate_byte(psmouse, psmouse->pktcnt - 1, priv->pkt_type) ? in synaptics_process_byte()
1276 int x_min = info->x_min ?: XMIN_NOMINAL; in set_abs_position_params()
1277 int x_max = info->x_max ?: XMAX_NOMINAL; in set_abs_position_params()
1278 int y_min = info->y_min ?: YMIN_NOMINAL; in set_abs_position_params()
1279 int y_max = info->y_max ?: YMAX_NOMINAL; in set_abs_position_params()
1280 int fuzz = SYN_CAP_REDUCED_FILTERING(info->ext_cap_0c) ? in set_abs_position_params()
1285 input_abs_set_res(dev, x_code, info->x_res); in set_abs_position_params()
1286 input_abs_set_res(dev, y_code, info->y_res); in set_abs_position_params()
1292 struct input_dev *dev = psmouse->dev; in set_input_params()
1293 struct synaptics_device_info *info = &priv->info; in set_input_params()
1298 __clear_bit(EV_REL, dev->evbit); in set_input_params()
1299 bitmap_zero(dev->relbit, REL_CNT); in set_input_params()
1300 bitmap_zero(dev->keybit, KEY_CNT); in set_input_params()
1303 __set_bit(INPUT_PROP_POINTER, dev->propbit); in set_input_params()
1307 /* Clickpads report only left button */ in set_input_params()
1308 if (!SYN_CAP_CLICKPAD(info->ext_cap_0c)) { in set_input_params()
1310 if (SYN_CAP_MIDDLE_BUTTON(info->capabilities)) in set_input_params()
1314 if (!priv->absolute_mode) { in set_input_params()
1322 set_abs_position_params(dev, &priv->info, ABS_X, ABS_Y); in set_input_params()
1328 if (SYN_CAP_IMAGE_SENSOR(info->ext_cap_0c)) { in set_input_params()
1331 /* Image sensors can report per-contact pressure */ in set_input_params()
1342 } else if (SYN_CAP_ADV_GESTURE(info->ext_cap_0c)) { in set_input_params()
1346 * Profile sensor in CR-48 tracks contacts reasonably well, in set_input_params()
1347 * other non-image sensors with AGM use semi-mt. in set_input_params()
1358 * For semi-mt devices we send ABS_X/Y ourselves instead of in set_input_params()
1362 * position. Let's re-initialize ABS_X/Y here. in set_input_params()
1365 set_abs_position_params(dev, &priv->info, ABS_X, ABS_Y); in set_input_params()
1368 if (SYN_CAP_PALMDETECT(info->capabilities)) in set_input_params()
1379 if (SYN_CAP_FOUR_BUTTON(info->capabilities) || in set_input_params()
1380 SYN_CAP_MIDDLE_BUTTON(info->capabilities)) { in set_input_params()
1385 if (!SYN_CAP_EXT_BUTTONS_STICK(info->ext_cap_10)) in set_input_params()
1386 for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(info->ext_cap); i++) in set_input_params()
1389 if (SYN_CAP_CLICKPAD(info->ext_cap_0c)) { in set_input_params()
1390 __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit); in set_input_params()
1392 !SYN_CAP_EXT_BUTTONS_STICK(info->ext_cap_10)) in set_input_params()
1393 __set_bit(INPUT_PROP_TOPBUTTONPAD, dev->propbit); in set_input_params()
1402 struct synaptics_data *priv = psmouse->private; in synaptics_show_disable_gesture()
1404 return sprintf(buf, "%c\n", priv->disable_gesture ? '1' : '0'); in synaptics_show_disable_gesture()
1411 struct synaptics_data *priv = psmouse->private; in synaptics_set_disable_gesture()
1420 return -EINVAL; in synaptics_set_disable_gesture()
1422 if (value == priv->disable_gesture) in synaptics_set_disable_gesture()
1425 priv->disable_gesture = value; in synaptics_set_disable_gesture()
1427 priv->mode |= SYN_BIT_DISABLE_GESTURE; in synaptics_set_disable_gesture()
1429 priv->mode &= ~SYN_BIT_DISABLE_GESTURE; in synaptics_set_disable_gesture()
1431 if (synaptics_mode_cmd(psmouse, priv->mode)) in synaptics_set_disable_gesture()
1432 return -EIO; in synaptics_set_disable_gesture()
1443 struct synaptics_data *priv = psmouse->private; in synaptics_disconnect()
1451 if (!priv->absolute_mode && in synaptics_disconnect()
1452 SYN_ID_DISGEST_SUPPORTED(priv->info.identity)) in synaptics_disconnect()
1453 device_remove_file(&psmouse->ps2dev.serio->dev, in synaptics_disconnect()
1458 psmouse->private = NULL; in synaptics_disconnect()
1463 struct synaptics_data *priv = psmouse->private; in synaptics_reconnect()
1476 * to Synaptics-specific queries, so let's wait a in synaptics_reconnect()
1481 ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_GETID); in synaptics_reconnect()
1503 if (info.identity != priv->info.identity || in synaptics_reconnect()
1504 info.model_id != priv->info.model_id || in synaptics_reconnect()
1505 info.capabilities != priv->info.capabilities || in synaptics_reconnect()
1506 info.ext_cap != priv->info.ext_cap) { in synaptics_reconnect()
1508 "hardware appears to be different: id(%u-%u), model(%u-%u), caps(%x-%x), ext(%x-%x).\n", in synaptics_reconnect()
1509 priv->info.identity, info.identity, in synaptics_reconnect()
1510 priv->info.model_id, info.model_id, in synaptics_reconnect()
1511 priv->info.capabilities, info.capabilities, in synaptics_reconnect()
1512 priv->info.ext_cap, info.ext_cap); in synaptics_reconnect()
1513 return -ENXIO; in synaptics_reconnect()
1563 /* OLPC XO-1 or XO-1.5 */
1576 /* Cr-48 Chromebook (Codename Mario) */
1602 psmouse->private = priv = kzalloc_obj(*priv); in synaptics_init_ps2()
1604 return -ENOMEM; in synaptics_init_ps2()
1606 priv->info = *info; in synaptics_init_ps2()
1607 priv->absolute_mode = absolute_mode; in synaptics_init_ps2()
1608 if (SYN_ID_DISGEST_SUPPORTED(info->identity)) in synaptics_init_ps2()
1609 priv->disable_gesture = true; in synaptics_init_ps2()
1615 priv->is_forcepad = psmouse_matches_pnp_id(psmouse, forcepad_pnp_ids); in synaptics_init_ps2()
1623 priv->pkt_type = SYN_MODEL_NEWABS(info->model_id) ? in synaptics_init_ps2()
1628 SYN_ID_MODEL(info->identity), in synaptics_init_ps2()
1629 SYN_ID_MAJOR(info->identity), SYN_ID_MINOR(info->identity), in synaptics_init_ps2()
1630 info->model_id, in synaptics_init_ps2()
1631 info->capabilities, info->ext_cap, info->ext_cap_0c, in synaptics_init_ps2()
1632 info->ext_cap_10, info->board_id, info->firmware_id); in synaptics_init_ps2()
1643 * input device->id.version and be visible to userspace. in synaptics_init_ps2()
1648 psmouse->model = ((info->model_id & 0x00ff0000) >> 8) | in synaptics_init_ps2()
1649 (info->model_id & 0x000000ff); in synaptics_init_ps2()
1652 psmouse->protocol_handler = synaptics_process_byte; in synaptics_init_ps2()
1653 psmouse->pktsize = 6; in synaptics_init_ps2()
1656 psmouse->protocol_handler = psmouse_process_byte; in synaptics_init_ps2()
1657 psmouse->pktsize = 3; in synaptics_init_ps2()
1660 psmouse->set_rate = synaptics_set_rate; in synaptics_init_ps2()
1661 psmouse->disconnect = synaptics_disconnect; in synaptics_init_ps2()
1662 psmouse->reconnect = synaptics_reconnect; in synaptics_init_ps2()
1663 psmouse->fast_reconnect = NULL; in synaptics_init_ps2()
1664 psmouse->cleanup = synaptics_reset; in synaptics_init_ps2()
1666 psmouse->resync_time = 0; in synaptics_init_ps2()
1668 if (SYN_CAP_PASS_THROUGH(info->capabilities)) in synaptics_init_ps2()
1676 if (psmouse->rate >= 80 && impaired_toshiba_kbc) { in synaptics_init_ps2()
1680 psmouse->rate = 40; in synaptics_init_ps2()
1683 if (!priv->absolute_mode && SYN_ID_DISGEST_SUPPORTED(info->identity)) { in synaptics_init_ps2()
1684 err = device_create_file(&psmouse->ps2dev.serio->dev, in synaptics_init_ps2()
1762 return -ENOSYS; in synaptics_setup_ps2()
1775 SYNAPTICS_INTERTOUCH_NOT_SET = -1,
1791 !SYN_CAP_EXT_BUTTONS_STICK(info->ext_cap_10); in synaptics_create_intertouch()
1801 .buttonpad = SYN_CAP_CLICKPAD(info->ext_cap_0c), in synaptics_create_intertouch()
1803 !!SYN_CAP_EXT_BUTTONS_STICK(info->ext_cap_10), in synaptics_create_intertouch()
1817 * synaptics_setup_intertouch - called once the PS/2 devices are enumerated
1827 return -ENXIO; in synaptics_setup_intertouch()
1836 …"If i2c-hid and hid-rmi are not used, you might want to try setting psmouse.synaptics_intertouch t… in synaptics_setup_intertouch()
1837 psmouse->ps2dev.serio->firmware_id); in synaptics_setup_intertouch()
1839 return -ENXIO; in synaptics_setup_intertouch()
1842 /* Disable intertouch on known-broken board revisions */ in synaptics_setup_intertouch()
1843 if (info->board_id == 2722) { in synaptics_setup_intertouch()
1846 info->board_id); in synaptics_setup_intertouch()
1847 return -ENXIO; in synaptics_setup_intertouch()
1855 if (error == -EAGAIN) in synaptics_setup_intertouch()
1880 return -ENXIO; in synaptics_init_smbus()
1892 return -ENOSYS; in synaptics_setup_intertouch()
1897 return -ENOSYS; in synaptics_init_smbus()
1950 return -ENOSYS; in synaptics_init()