Lines Matching +full:trackpad +full:- +full:3 +full:x

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Cypress Trackpad PS/2 mouse driver
31 struct cytp_data *cytp = psmouse->private; in cypress_set_packet_size()
32 cytp->pkt_size = n; in cypress_set_packet_size()
40 struct ps2dev *ps2dev = &psmouse->ps2dev; in cypress_ps2_sendbyte()
44 "sending command 0x%02x failed, resp 0x%02x\n", in cypress_ps2_sendbyte()
45 value & 0xff, ps2dev->nak); in cypress_ps2_sendbyte()
46 if (ps2dev->nak == CYTP_PS2_RETRY) in cypress_ps2_sendbyte()
53 psmouse_dbg(psmouse, "sending command 0x%02x succeeded, resp 0xfa\n", in cypress_ps2_sendbyte()
63 struct ps2dev *ps2dev = &psmouse->ps2dev; in cypress_ps2_ext_cmd()
91 } while (--tries > 0); in cypress_ps2_ext_cmd()
103 struct ps2dev *ps2dev = &psmouse->ps2dev; in cypress_ps2_read_cmd_status()
109 old_state = psmouse->state; in cypress_ps2_read_cmd_status()
110 psmouse->state = PSMOUSE_CMD_MODE; in cypress_ps2_read_cmd_status()
111 psmouse->pktcnt = 0; in cypress_ps2_read_cmd_status()
113 pktsize = (cmd == CYTP_CMD_READ_TP_METRICS) ? 8 : 3; in cypress_ps2_read_cmd_status()
120 wait_event_timeout(ps2dev->wait, in cypress_ps2_read_cmd_status()
121 (psmouse->pktcnt >= pktsize), in cypress_ps2_read_cmd_status()
124 memcpy(param, psmouse->packet, pktsize); in cypress_ps2_read_cmd_status()
126 psmouse_dbg(psmouse, "Command 0x%02x response data (0x): %*ph\n", in cypress_ps2_read_cmd_status()
130 psmouse->state = old_state; in cypress_ps2_read_cmd_status()
131 psmouse->pktcnt = 0; in cypress_ps2_read_cmd_status()
175 psmouse_dbg(psmouse, "send extension cmd 0x%02x, [%d %d %d %d]\n", in cypress_send_ext_cmd()
196 } while (--tries > 0); in cypress_send_ext_cmd()
198 return -EIO; in cypress_send_ext_cmd()
203 unsigned char param[3]; in cypress_detect()
206 return -ENODEV; in cypress_detect()
208 /* Check for Cypress Trackpad signature bytes: 0x33 0xCC */ in cypress_detect()
210 return -ENODEV; in cypress_detect()
213 psmouse->vendor = "Cypress"; in cypress_detect()
214 psmouse->name = "Trackpad"; in cypress_detect()
222 struct cytp_data *cytp = psmouse->private; in cypress_read_fw_version()
223 unsigned char param[3]; in cypress_read_fw_version()
226 return -ENODEV; in cypress_read_fw_version()
228 /* Check for Cypress Trackpad signature bytes: 0x33 0xCC */ in cypress_read_fw_version()
230 return -ENODEV; in cypress_read_fw_version()
232 cytp->fw_version = param[2] & FW_VERSION_MASX; in cypress_read_fw_version()
233 cytp->tp_metrics_supported = (param[2] & TP_METRICS_MASK) ? 1 : 0; in cypress_read_fw_version()
236 * Trackpad fw_version 11 (in Dell XPS12) yields a bogus response to in cypress_read_fw_version()
239 if (cytp->fw_version >= 11) in cypress_read_fw_version()
240 cytp->tp_metrics_supported = 0; in cypress_read_fw_version()
242 psmouse_dbg(psmouse, "cytp->fw_version = %d\n", cytp->fw_version); in cypress_read_fw_version()
243 psmouse_dbg(psmouse, "cytp->tp_metrics_supported = %d\n", in cypress_read_fw_version()
244 cytp->tp_metrics_supported); in cypress_read_fw_version()
251 struct cytp_data *cytp = psmouse->private; in cypress_read_tp_metrics()
255 cytp->tp_width = CYTP_DEFAULT_WIDTH; in cypress_read_tp_metrics()
256 cytp->tp_high = CYTP_DEFAULT_HIGH; in cypress_read_tp_metrics()
257 cytp->tp_max_abs_x = CYTP_ABS_MAX_X; in cypress_read_tp_metrics()
258 cytp->tp_max_abs_y = CYTP_ABS_MAX_Y; in cypress_read_tp_metrics()
259 cytp->tp_min_pressure = CYTP_MIN_PRESSURE; in cypress_read_tp_metrics()
260 cytp->tp_max_pressure = CYTP_MAX_PRESSURE; in cypress_read_tp_metrics()
261 cytp->tp_res_x = cytp->tp_max_abs_x / cytp->tp_width; in cypress_read_tp_metrics()
262 cytp->tp_res_y = cytp->tp_max_abs_y / cytp->tp_high; in cypress_read_tp_metrics()
264 if (!cytp->tp_metrics_supported) in cypress_read_tp_metrics()
269 /* Update trackpad parameters. */ in cypress_read_tp_metrics()
270 cytp->tp_max_abs_x = (param[1] << 8) | param[0]; in cypress_read_tp_metrics()
271 cytp->tp_max_abs_y = (param[3] << 8) | param[2]; in cypress_read_tp_metrics()
272 cytp->tp_min_pressure = param[4]; in cypress_read_tp_metrics()
273 cytp->tp_max_pressure = param[5]; in cypress_read_tp_metrics()
276 if (!cytp->tp_max_pressure || in cypress_read_tp_metrics()
277 cytp->tp_max_pressure < cytp->tp_min_pressure || in cypress_read_tp_metrics()
278 !cytp->tp_width || !cytp->tp_high || in cypress_read_tp_metrics()
279 !cytp->tp_max_abs_x || in cypress_read_tp_metrics()
280 cytp->tp_max_abs_x < cytp->tp_width || in cypress_read_tp_metrics()
281 !cytp->tp_max_abs_y || in cypress_read_tp_metrics()
282 cytp->tp_max_abs_y < cytp->tp_high) in cypress_read_tp_metrics()
283 return -EINVAL; in cypress_read_tp_metrics()
285 cytp->tp_res_x = cytp->tp_max_abs_x / cytp->tp_width; in cypress_read_tp_metrics()
286 cytp->tp_res_y = cytp->tp_max_abs_y / cytp->tp_high; in cypress_read_tp_metrics()
289 psmouse_dbg(psmouse, "Dump trackpad hardware configuration as below:\n"); in cypress_read_tp_metrics()
290 psmouse_dbg(psmouse, "cytp->tp_width = %d\n", cytp->tp_width); in cypress_read_tp_metrics()
291 psmouse_dbg(psmouse, "cytp->tp_high = %d\n", cytp->tp_high); in cypress_read_tp_metrics()
292 psmouse_dbg(psmouse, "cytp->tp_max_abs_x = %d\n", cytp->tp_max_abs_x); in cypress_read_tp_metrics()
293 psmouse_dbg(psmouse, "cytp->tp_max_abs_y = %d\n", cytp->tp_max_abs_y); in cypress_read_tp_metrics()
294 psmouse_dbg(psmouse, "cytp->tp_min_pressure = %d\n", cytp->tp_min_pressure); in cypress_read_tp_metrics()
295 psmouse_dbg(psmouse, "cytp->tp_max_pressure = %d\n", cytp->tp_max_pressure); in cypress_read_tp_metrics()
296 psmouse_dbg(psmouse, "cytp->tp_res_x = %d\n", cytp->tp_res_x); in cypress_read_tp_metrics()
297 psmouse_dbg(psmouse, "cytp->tp_res_y = %d\n", cytp->tp_res_y); in cypress_read_tp_metrics()
339 struct cytp_data *cytp = psmouse->private; in cypress_set_absolute_mode()
340 unsigned char param[3]; in cypress_set_absolute_mode()
343 return -1; in cypress_set_absolute_mode()
345 cytp->mode = (cytp->mode & ~CYTP_BIT_ABS_REL_MASK) in cypress_set_absolute_mode()
353 * Reset trackpad device.
354 * This is also the default mode when trackpad powered on.
358 struct cytp_data *cytp = psmouse->private; in cypress_reset()
360 cytp->mode = 0; in cypress_reset()
370 if (!cytp->tp_res_x || !cytp->tp_res_y) in cypress_set_input_params()
371 return -EINVAL; in cypress_set_input_params()
373 __set_bit(EV_ABS, input->evbit); in cypress_set_input_params()
374 input_set_abs_params(input, ABS_X, 0, cytp->tp_max_abs_x, 0, 0); in cypress_set_input_params()
375 input_set_abs_params(input, ABS_Y, 0, cytp->tp_max_abs_y, 0, 0); in cypress_set_input_params()
377 cytp->tp_min_pressure, cytp->tp_max_pressure, 0, 0); in cypress_set_input_params()
381 input_set_abs_params(input, ABS_MT_POSITION_X, 0, cytp->tp_max_abs_x, 0, 0); in cypress_set_input_params()
382 input_set_abs_params(input, ABS_MT_POSITION_Y, 0, cytp->tp_max_abs_y, 0, 0); in cypress_set_input_params()
390 __set_bit(INPUT_PROP_SEMI_MT, input->propbit); in cypress_set_input_params()
392 input_abs_set_res(input, ABS_X, cytp->tp_res_x); in cypress_set_input_params()
393 input_abs_set_res(input, ABS_Y, cytp->tp_res_y); in cypress_set_input_params()
395 input_abs_set_res(input, ABS_MT_POSITION_X, cytp->tp_res_x); in cypress_set_input_params()
396 input_abs_set_res(input, ABS_MT_POSITION_Y, cytp->tp_res_y); in cypress_set_input_params()
398 __set_bit(BTN_TOUCH, input->keybit); in cypress_set_input_params()
399 __set_bit(BTN_TOOL_FINGER, input->keybit); in cypress_set_input_params()
400 __set_bit(BTN_TOOL_DOUBLETAP, input->keybit); in cypress_set_input_params()
401 __set_bit(BTN_TOOL_TRIPLETAP, input->keybit); in cypress_set_input_params()
402 __set_bit(BTN_TOOL_QUADTAP, input->keybit); in cypress_set_input_params()
403 __set_bit(BTN_TOOL_QUINTTAP, input->keybit); in cypress_set_input_params()
405 __clear_bit(EV_REL, input->evbit); in cypress_set_input_params()
406 __clear_bit(REL_X, input->relbit); in cypress_set_input_params()
407 __clear_bit(REL_Y, input->relbit); in cypress_set_input_params()
409 __set_bit(EV_KEY, input->evbit); in cypress_set_input_params()
410 __set_bit(BTN_LEFT, input->keybit); in cypress_set_input_params()
411 __set_bit(BTN_RIGHT, input->keybit); in cypress_set_input_params()
412 __set_bit(BTN_MIDDLE, input->keybit); in cypress_set_input_params()
446 unsigned char *packet = psmouse->packet; in cypress_parse_packet()
451 report_data->contact_cnt = cypress_get_finger_count(header_byte); in cypress_parse_packet()
452 report_data->tap = (header_byte & ABS_MULTIFINGER_TAP) ? 1 : 0; in cypress_parse_packet()
454 if (report_data->contact_cnt == 1) { in cypress_parse_packet()
455 report_data->contacts[0].x = in cypress_parse_packet()
457 report_data->contacts[0].y = in cypress_parse_packet()
458 ((packet[1] & 0x07) << 8) | packet[3]; in cypress_parse_packet()
459 if (cytp->mode & CYTP_BIT_ABS_PRESSURE) in cypress_parse_packet()
460 report_data->contacts[0].z = packet[4]; in cypress_parse_packet()
462 } else if (report_data->contact_cnt >= 2) { in cypress_parse_packet()
463 report_data->contacts[0].x = in cypress_parse_packet()
465 report_data->contacts[0].y = in cypress_parse_packet()
466 ((packet[1] & 0x07) << 8) | packet[3]; in cypress_parse_packet()
467 if (cytp->mode & CYTP_BIT_ABS_PRESSURE) in cypress_parse_packet()
468 report_data->contacts[0].z = packet[4]; in cypress_parse_packet()
470 report_data->contacts[1].x = in cypress_parse_packet()
472 report_data->contacts[1].y = in cypress_parse_packet()
474 if (cytp->mode & CYTP_BIT_ABS_PRESSURE) in cypress_parse_packet()
475 report_data->contacts[1].z = report_data->contacts[0].z; in cypress_parse_packet()
478 report_data->left = (header_byte & BTN_LEFT_BIT) ? 1 : 0; in cypress_parse_packet()
479 report_data->right = (header_byte & BTN_RIGHT_BIT) ? 1 : 0; in cypress_parse_packet()
483 * sure it doesn't turn into a click. The regular tap-to-click in cypress_parse_packet()
485 * disabling tap-to-click won't affect the mouse button zones. in cypress_parse_packet()
487 if (report_data->tap) in cypress_parse_packet()
488 report_data->left = 0; in cypress_parse_packet()
493 int n = report_data->contact_cnt; in cypress_parse_packet()
496 report_data->contact_cnt); in cypress_parse_packet()
501 report_data->contacts[i].x, in cypress_parse_packet()
502 report_data->contacts[i].y, in cypress_parse_packet()
503 report_data->contacts[i].z); in cypress_parse_packet()
504 psmouse_dbg(psmouse, "left = %d\n", report_data->left); in cypress_parse_packet()
505 psmouse_dbg(psmouse, "right = %d\n", report_data->right); in cypress_parse_packet()
506 psmouse_dbg(psmouse, "middle = %d\n", report_data->middle); in cypress_parse_packet()
516 struct input_dev *input = psmouse->dev; in cypress_process_packet()
517 struct cytp_data *cytp = psmouse->private; in cypress_process_packet()
532 pos[i].x = contact->x; in cypress_process_packet()
533 pos[i].y = contact->y; in cypress_process_packet()
542 input_report_abs(input, ABS_MT_POSITION_X, contact->x); in cypress_process_packet()
543 input_report_abs(input, ABS_MT_POSITION_Y, contact->y); in cypress_process_packet()
544 input_report_abs(input, ABS_MT_PRESSURE, contact->z); in cypress_process_packet()
561 int index = psmouse->pktcnt - 1; in cypress_validate_byte()
562 unsigned char *packet = psmouse->packet; in cypress_validate_byte()
563 struct cytp_data *cytp = psmouse->private; in cypress_validate_byte()
565 if (index < 0 || index > cytp->pkt_size) in cypress_validate_byte()
585 if ((cytp->mode & CYTP_BIT_ABS_REL_MASK) == 0) in cypress_validate_byte()
592 if (cytp->mode & CYTP_BIT_ABS_NO_PRESSURE) in cypress_validate_byte()
602 struct cytp_data *cytp = psmouse->private; in cypress_protocol_handler()
604 if (psmouse->pktcnt >= cytp->pkt_size) { in cypress_protocol_handler()
614 struct cytp_data *cytp = psmouse->private; in cypress_set_rate()
617 psmouse->rate = 80; in cypress_set_rate()
618 cytp->mode |= CYTP_BIT_HIGH_RATE; in cypress_set_rate()
620 psmouse->rate = 40; in cypress_set_rate()
621 cytp->mode &= ~CYTP_BIT_HIGH_RATE; in cypress_set_rate()
624 ps2_command(&psmouse->ps2dev, (unsigned char *)&psmouse->rate, in cypress_set_rate()
631 kfree(psmouse->private); in cypress_disconnect()
632 psmouse->private = NULL; in cypress_disconnect()
643 } while (rc && (--tries > 0)); in cypress_reconnect()
646 psmouse_err(psmouse, "Reconnect: unable to detect trackpad.\n"); in cypress_reconnect()
647 return -1; in cypress_reconnect()
652 return -1; in cypress_reconnect()
664 return -ENOMEM; in cypress_init()
666 psmouse->private = cytp; in cypress_init()
667 psmouse->pktsize = 8; in cypress_init()
672 psmouse_err(psmouse, "Unable to query Trackpad hardware.\n"); in cypress_init()
681 if (cypress_set_input_params(psmouse->dev, cytp) < 0) { in cypress_init()
686 psmouse->model = 1; in cypress_init()
687 psmouse->protocol_handler = cypress_protocol_handler; in cypress_init()
688 psmouse->set_rate = cypress_set_rate; in cypress_init()
689 psmouse->disconnect = cypress_disconnect; in cypress_init()
690 psmouse->reconnect = cypress_reconnect; in cypress_init()
691 psmouse->cleanup = cypress_reset; in cypress_init()
692 psmouse->resync_time = 0; in cypress_init()
698 * Reset Cypress Trackpad as a standard mouse. Then in cypress_init()
703 psmouse->private = NULL; in cypress_init()
706 return -1; in cypress_init()