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()
46 "sending command 0x%02x failed, resp 0x%02x, error %d\n", in cypress_ps2_sendbyte()
47 cmd, ps2dev->nak, error); in cypress_ps2_sendbyte()
52 psmouse_dbg(psmouse, "sending command 0x%02x succeeded\n", cmd); in cypress_ps2_sendbyte()
60 struct ps2dev *ps2dev = &psmouse->ps2dev; in cypress_ps2_ext_cmd()
73 if (rc == -EAGAIN) { in cypress_ps2_ext_cmd()
75 if (rc == -EAGAIN) in cypress_ps2_ext_cmd()
81 if (rc == -EAGAIN) in cypress_ps2_ext_cmd()
87 } while (--tries > 0); in cypress_ps2_ext_cmd()
127 unsigned int resp_size = cmd == CYTP_CMD_READ_TP_METRICS ? 8 : 3; in cypress_send_ext_cmd()
132 psmouse_dbg(psmouse, "send extension cmd 0x%02x, [%d %d %d %d]\n", in cypress_send_ext_cmd()
142 error = ps2_command(&psmouse->ps2dev, param, ps2_cmd); in cypress_send_ext_cmd()
144 psmouse_dbg(psmouse, "Command 0x%02x failed: %d\n", in cypress_send_ext_cmd()
148 "Command 0x%02x response data (0x): %*ph\n", in cypress_send_ext_cmd()
154 } while (--tries > 0); in cypress_send_ext_cmd()
156 return -EIO; in cypress_send_ext_cmd()
161 u8 param[3]; in cypress_detect()
164 return -ENODEV; in cypress_detect()
166 /* Check for Cypress Trackpad signature bytes: 0x33 0xCC */ in cypress_detect()
168 return -ENODEV; in cypress_detect()
171 psmouse->vendor = "Cypress"; in cypress_detect()
172 psmouse->name = "Trackpad"; in cypress_detect()
180 struct cytp_data *cytp = psmouse->private; in cypress_read_fw_version()
181 u8 param[3]; in cypress_read_fw_version()
184 return -ENODEV; in cypress_read_fw_version()
186 /* Check for Cypress Trackpad signature bytes: 0x33 0xCC */ in cypress_read_fw_version()
188 return -ENODEV; in cypress_read_fw_version()
190 cytp->fw_version = param[2] & FW_VERSION_MASX; in cypress_read_fw_version()
191 cytp->tp_metrics_supported = (param[2] & TP_METRICS_MASK) ? 1 : 0; in cypress_read_fw_version()
194 * Trackpad fw_version 11 (in Dell XPS12) yields a bogus response to in cypress_read_fw_version()
197 if (cytp->fw_version >= 11) in cypress_read_fw_version()
198 cytp->tp_metrics_supported = 0; in cypress_read_fw_version()
200 psmouse_dbg(psmouse, "cytp->fw_version = %d\n", cytp->fw_version); in cypress_read_fw_version()
201 psmouse_dbg(psmouse, "cytp->tp_metrics_supported = %d\n", in cypress_read_fw_version()
202 cytp->tp_metrics_supported); in cypress_read_fw_version()
209 struct cytp_data *cytp = psmouse->private; in cypress_read_tp_metrics()
213 cytp->tp_width = CYTP_DEFAULT_WIDTH; in cypress_read_tp_metrics()
214 cytp->tp_high = CYTP_DEFAULT_HIGH; in cypress_read_tp_metrics()
215 cytp->tp_max_abs_x = CYTP_ABS_MAX_X; in cypress_read_tp_metrics()
216 cytp->tp_max_abs_y = CYTP_ABS_MAX_Y; in cypress_read_tp_metrics()
217 cytp->tp_min_pressure = CYTP_MIN_PRESSURE; in cypress_read_tp_metrics()
218 cytp->tp_max_pressure = CYTP_MAX_PRESSURE; in cypress_read_tp_metrics()
219 cytp->tp_res_x = cytp->tp_max_abs_x / cytp->tp_width; in cypress_read_tp_metrics()
220 cytp->tp_res_y = cytp->tp_max_abs_y / cytp->tp_high; in cypress_read_tp_metrics()
222 if (!cytp->tp_metrics_supported) in cypress_read_tp_metrics()
227 /* Update trackpad parameters. */ in cypress_read_tp_metrics()
228 cytp->tp_max_abs_x = (param[1] << 8) | param[0]; in cypress_read_tp_metrics()
229 cytp->tp_max_abs_y = (param[3] << 8) | param[2]; in cypress_read_tp_metrics()
230 cytp->tp_min_pressure = param[4]; in cypress_read_tp_metrics()
231 cytp->tp_max_pressure = param[5]; in cypress_read_tp_metrics()
234 if (!cytp->tp_max_pressure || in cypress_read_tp_metrics()
235 cytp->tp_max_pressure < cytp->tp_min_pressure || in cypress_read_tp_metrics()
236 !cytp->tp_width || !cytp->tp_high || in cypress_read_tp_metrics()
237 !cytp->tp_max_abs_x || in cypress_read_tp_metrics()
238 cytp->tp_max_abs_x < cytp->tp_width || in cypress_read_tp_metrics()
239 !cytp->tp_max_abs_y || in cypress_read_tp_metrics()
240 cytp->tp_max_abs_y < cytp->tp_high) in cypress_read_tp_metrics()
241 return -EINVAL; in cypress_read_tp_metrics()
243 cytp->tp_res_x = cytp->tp_max_abs_x / cytp->tp_width; in cypress_read_tp_metrics()
244 cytp->tp_res_y = cytp->tp_max_abs_y / cytp->tp_high; in cypress_read_tp_metrics()
247 psmouse_dbg(psmouse, "Dump trackpad hardware configuration as below:\n"); in cypress_read_tp_metrics()
248 psmouse_dbg(psmouse, "cytp->tp_width = %d\n", cytp->tp_width); in cypress_read_tp_metrics()
249 psmouse_dbg(psmouse, "cytp->tp_high = %d\n", cytp->tp_high); in cypress_read_tp_metrics()
250 psmouse_dbg(psmouse, "cytp->tp_max_abs_x = %d\n", cytp->tp_max_abs_x); in cypress_read_tp_metrics()
251 psmouse_dbg(psmouse, "cytp->tp_max_abs_y = %d\n", cytp->tp_max_abs_y); in cypress_read_tp_metrics()
252 psmouse_dbg(psmouse, "cytp->tp_min_pressure = %d\n", cytp->tp_min_pressure); in cypress_read_tp_metrics()
253 psmouse_dbg(psmouse, "cytp->tp_max_pressure = %d\n", cytp->tp_max_pressure); in cypress_read_tp_metrics()
254 psmouse_dbg(psmouse, "cytp->tp_res_x = %d\n", cytp->tp_res_x); in cypress_read_tp_metrics()
255 psmouse_dbg(psmouse, "cytp->tp_res_y = %d\n", cytp->tp_res_y); in cypress_read_tp_metrics()
297 struct cytp_data *cytp = psmouse->private; in cypress_set_absolute_mode()
298 u8 param[3]; in cypress_set_absolute_mode()
306 cytp->mode = (cytp->mode & ~CYTP_BIT_ABS_REL_MASK) in cypress_set_absolute_mode()
314 * Reset trackpad device.
315 * This is also the default mode when trackpad powered on.
319 struct cytp_data *cytp = psmouse->private; in cypress_reset()
321 cytp->mode = 0; in cypress_reset()
331 if (!cytp->tp_res_x || !cytp->tp_res_y) in cypress_set_input_params()
332 return -EINVAL; in cypress_set_input_params()
334 __set_bit(EV_ABS, input->evbit); in cypress_set_input_params()
335 input_set_abs_params(input, ABS_X, 0, cytp->tp_max_abs_x, 0, 0); in cypress_set_input_params()
336 input_set_abs_params(input, ABS_Y, 0, cytp->tp_max_abs_y, 0, 0); in cypress_set_input_params()
338 cytp->tp_min_pressure, cytp->tp_max_pressure, 0, 0); in cypress_set_input_params()
342 input_set_abs_params(input, ABS_MT_POSITION_X, 0, cytp->tp_max_abs_x, 0, 0); in cypress_set_input_params()
343 input_set_abs_params(input, ABS_MT_POSITION_Y, 0, cytp->tp_max_abs_y, 0, 0); in cypress_set_input_params()
351 __set_bit(INPUT_PROP_SEMI_MT, input->propbit); in cypress_set_input_params()
353 input_abs_set_res(input, ABS_X, cytp->tp_res_x); in cypress_set_input_params()
354 input_abs_set_res(input, ABS_Y, cytp->tp_res_y); in cypress_set_input_params()
356 input_abs_set_res(input, ABS_MT_POSITION_X, cytp->tp_res_x); in cypress_set_input_params()
357 input_abs_set_res(input, ABS_MT_POSITION_Y, cytp->tp_res_y); in cypress_set_input_params()
359 __set_bit(BTN_TOUCH, input->keybit); in cypress_set_input_params()
360 __set_bit(BTN_TOOL_FINGER, input->keybit); in cypress_set_input_params()
361 __set_bit(BTN_TOOL_DOUBLETAP, input->keybit); in cypress_set_input_params()
362 __set_bit(BTN_TOOL_TRIPLETAP, input->keybit); in cypress_set_input_params()
363 __set_bit(BTN_TOOL_QUADTAP, input->keybit); in cypress_set_input_params()
364 __set_bit(BTN_TOOL_QUINTTAP, input->keybit); in cypress_set_input_params()
366 __clear_bit(EV_REL, input->evbit); in cypress_set_input_params()
367 __clear_bit(REL_X, input->relbit); in cypress_set_input_params()
368 __clear_bit(REL_Y, input->relbit); in cypress_set_input_params()
370 __set_bit(EV_KEY, input->evbit); in cypress_set_input_params()
371 __set_bit(BTN_LEFT, input->keybit); in cypress_set_input_params()
372 __set_bit(BTN_RIGHT, input->keybit); in cypress_set_input_params()
373 __set_bit(BTN_MIDDLE, input->keybit); in cypress_set_input_params()
408 u8 *packet = psmouse->packet; in cypress_parse_packet()
413 report_data->contact_cnt = cypress_get_finger_count(header_byte); in cypress_parse_packet()
414 report_data->tap = (header_byte & ABS_MULTIFINGER_TAP) ? 1 : 0; in cypress_parse_packet()
416 if (report_data->contact_cnt == 1) { in cypress_parse_packet()
417 report_data->contacts[0].x = in cypress_parse_packet()
419 report_data->contacts[0].y = in cypress_parse_packet()
420 ((packet[1] & 0x07) << 8) | packet[3]; in cypress_parse_packet()
421 if (cytp->mode & CYTP_BIT_ABS_PRESSURE) in cypress_parse_packet()
422 report_data->contacts[0].z = packet[4]; in cypress_parse_packet()
424 } else if (report_data->contact_cnt >= 2) { in cypress_parse_packet()
425 report_data->contacts[0].x = in cypress_parse_packet()
427 report_data->contacts[0].y = in cypress_parse_packet()
428 ((packet[1] & 0x07) << 8) | packet[3]; in cypress_parse_packet()
429 if (cytp->mode & CYTP_BIT_ABS_PRESSURE) in cypress_parse_packet()
430 report_data->contacts[0].z = packet[4]; in cypress_parse_packet()
432 report_data->contacts[1].x = in cypress_parse_packet()
434 report_data->contacts[1].y = in cypress_parse_packet()
436 if (cytp->mode & CYTP_BIT_ABS_PRESSURE) in cypress_parse_packet()
437 report_data->contacts[1].z = report_data->contacts[0].z; in cypress_parse_packet()
440 report_data->left = (header_byte & BTN_LEFT_BIT) ? 1 : 0; in cypress_parse_packet()
441 report_data->right = (header_byte & BTN_RIGHT_BIT) ? 1 : 0; in cypress_parse_packet()
445 * sure it doesn't turn into a click. The regular tap-to-click in cypress_parse_packet()
447 * disabling tap-to-click won't affect the mouse button zones. in cypress_parse_packet()
449 if (report_data->tap) in cypress_parse_packet()
450 report_data->left = 0; in cypress_parse_packet()
455 int n = report_data->contact_cnt; in cypress_parse_packet()
458 report_data->contact_cnt); in cypress_parse_packet()
463 report_data->contacts[i].x, in cypress_parse_packet()
464 report_data->contacts[i].y, in cypress_parse_packet()
465 report_data->contacts[i].z); in cypress_parse_packet()
466 psmouse_dbg(psmouse, "left = %d\n", report_data->left); in cypress_parse_packet()
467 psmouse_dbg(psmouse, "right = %d\n", report_data->right); in cypress_parse_packet()
468 psmouse_dbg(psmouse, "middle = %d\n", report_data->middle); in cypress_parse_packet()
478 struct input_dev *input = psmouse->dev; in cypress_process_packet()
479 struct cytp_data *cytp = psmouse->private; in cypress_process_packet()
494 pos[i].x = contact->x; in cypress_process_packet()
495 pos[i].y = contact->y; in cypress_process_packet()
504 input_report_abs(input, ABS_MT_POSITION_X, contact->x); in cypress_process_packet()
505 input_report_abs(input, ABS_MT_POSITION_Y, contact->y); in cypress_process_packet()
506 input_report_abs(input, ABS_MT_PRESSURE, contact->z); in cypress_process_packet()
523 int index = psmouse->pktcnt - 1; in cypress_validate_byte()
524 u8 *packet = psmouse->packet; in cypress_validate_byte()
525 struct cytp_data *cytp = psmouse->private; in cypress_validate_byte()
527 if (index < 0 || index > cytp->pkt_size) in cypress_validate_byte()
547 if ((cytp->mode & CYTP_BIT_ABS_REL_MASK) == 0) in cypress_validate_byte()
554 if (cytp->mode & CYTP_BIT_ABS_NO_PRESSURE) in cypress_validate_byte()
564 struct cytp_data *cytp = psmouse->private; in cypress_protocol_handler()
566 if (psmouse->pktcnt >= cytp->pkt_size) { in cypress_protocol_handler()
576 struct cytp_data *cytp = psmouse->private; in cypress_set_rate()
580 psmouse->rate = 80; in cypress_set_rate()
581 cytp->mode |= CYTP_BIT_HIGH_RATE; in cypress_set_rate()
583 psmouse->rate = 40; in cypress_set_rate()
584 cytp->mode &= ~CYTP_BIT_HIGH_RATE; in cypress_set_rate()
588 ps2_command(&psmouse->ps2dev, &rate_param, PSMOUSE_CMD_SETRATE); in cypress_set_rate()
594 kfree(psmouse->private); in cypress_disconnect()
595 psmouse->private = NULL; in cypress_disconnect()
606 } while (error && (--tries > 0)); in cypress_reconnect()
609 psmouse_err(psmouse, "Reconnect: unable to detect trackpad.\n"); in cypress_reconnect()
629 return -ENOMEM; in cypress_init()
631 psmouse->private = cytp; in cypress_init()
632 psmouse->pktsize = 8; in cypress_init()
638 psmouse_err(psmouse, "Unable to query Trackpad hardware.\n"); in cypress_init()
648 error = cypress_set_input_params(psmouse->dev, cytp); in cypress_init()
654 psmouse->model = 1; in cypress_init()
655 psmouse->protocol_handler = cypress_protocol_handler; in cypress_init()
656 psmouse->set_rate = cypress_set_rate; in cypress_init()
657 psmouse->disconnect = cypress_disconnect; in cypress_init()
658 psmouse->reconnect = cypress_reconnect; in cypress_init()
659 psmouse->cleanup = cypress_reset; in cypress_init()
660 psmouse->resync_time = 0; in cypress_init()
666 * Reset Cypress Trackpad as a standard mouse. Then in cypress_init()
671 psmouse->private = NULL; in cypress_init()