From c3a3b68d59a64d59e38e28bc94f579bff6a24536 Mon Sep 17 00:00:00 2001 From: Jeff Leung Date: Sun, 28 Apr 2024 02:16:02 +0800 Subject: [PATCH 1/5] disable config ZMK_INPUT_MOUSE_PS2 depends on split role --- src/drivers/input/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/drivers/input/Kconfig b/src/drivers/input/Kconfig index 790c4af..ee6f8b6 100644 --- a/src/drivers/input/Kconfig +++ b/src/drivers/input/Kconfig @@ -6,7 +6,7 @@ DT_COMPAT_ZMK_INPUT_PS2_MOUSE := zmk,input-mouse-ps2 config ZMK_INPUT_MOUSE_PS2 bool default $(dt_compat_enabled,$(DT_COMPAT_ZMK_INPUT_PS2_MOUSE)) - depends on (!ZMK_SPLIT || ZMK_SPLIT_ROLE_CENTRAL) + # depends on (!ZMK_SPLIT || ZMK_SPLIT_ROLE_CENTRAL) select ZMK_MOUSE select PS2 From c119114eed16bf00ec954754faa1a97868e4736e Mon Sep 17 00:00:00 2001 From: Jeff Leung Date: Fri, 3 May 2024 01:19:12 +0800 Subject: [PATCH 2/5] add CONFIG_ZMK_INPUT_MOUSE_PS2_REPORT_INTERVAL_MIN --- src/drivers/input/Kconfig | 7 ++++++ src/drivers/input/input_mouse_ps2.c | 33 +++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/src/drivers/input/Kconfig b/src/drivers/input/Kconfig index ee6f8b6..37630ed 100644 --- a/src/drivers/input/Kconfig +++ b/src/drivers/input/Kconfig @@ -24,4 +24,11 @@ config ZMK_INPUT_MOUSE_PS2_ENABLE_ERROR_MITIGATION bool "Tries to mitigate transmission errors. Only useful when using a PS2 driver that is prone to miscommunication like the GPIO bitbanging driver." default n +config ZMK_INPUT_MOUSE_PS2_REPORT_INTERVAL_MIN + int "Minimum report rate. Use to avoid bluetooth queue overflow." + default 0 + help + Default minimum report interval in milliseconds. + Slow down input reporting for hid queue over the air. + endif # ZMK_INPUT_MOUSE_PS2 diff --git a/src/drivers/input/input_mouse_ps2.c b/src/drivers/input/input_mouse_ps2.c index e32c92b..ddb4286 100644 --- a/src/drivers/input/input_mouse_ps2.c +++ b/src/drivers/input/input_mouse_ps2.c @@ -516,12 +516,45 @@ void zmk_mouse_ps2_activity_move_mouse(int16_t mov_x, int16_t mov_y) { bool have_x = zmk_mouse_ps2_is_non_zero_1d_movement(mov_x); bool have_y = zmk_mouse_ps2_is_non_zero_1d_movement(mov_y); + +#if CONFIG_ZMK_INPUT_MOUSE_PS2_REPORT_INTERVAL_MIN > 0 + + static int64_t adx = 0; + static int64_t ady = 0; + static int64_t last_smp_time = 0; + static int64_t last_rpt_time = 0; + int64_t now = k_uptime_get(); + if (now - last_smp_time >= CONFIG_ZMK_INPUT_MOUSE_PS2_REPORT_INTERVAL_MIN) { + adx = ady = 0; + } + last_smp_time = now; + adx += mov_x; + ady += mov_y; + if (now - last_rpt_time < CONFIG_ZMK_INPUT_MOUSE_PS2_REPORT_INTERVAL_MIN) { + return; + } + if (have_x || have_y) { + last_rpt_time = now; + if (have_x) { + ret = input_report_rel(data->dev, INPUT_REL_X, adx, !have_y, K_NO_WAIT); + } + if (have_y) { + ret = input_report_rel(data->dev, INPUT_REL_Y, ady, true, K_NO_WAIT); + } + adx = ady = 0; + } + +#else /* CONFIG_ZMK_INPUT_MOUSE_PS2_REPORT_INTERVAL_MIN > 0 */ + if (have_x) { ret = input_report_rel(data->dev, INPUT_REL_X, mov_x, !have_y, K_NO_WAIT); } if (have_y) { ret = input_report_rel(data->dev, INPUT_REL_Y, mov_y, true, K_NO_WAIT); } + +#endif /* CONFIG_ZMK_INPUT_MOUSE_PS2_REPORT_INTERVAL_MIN > 0 */ + } void zmk_mouse_ps2_activity_click_buttons(bool button_l, bool button_m, bool button_r) { From f291157917a0cbac629305eba009f8fdafbf559d Mon Sep 17 00:00:00 2001 From: Jeff Leung Date: Tue, 28 May 2024 01:31:10 +0800 Subject: [PATCH 3/5] refactor: multi instance --- src/drivers/input/input_mouse_ps2.c | 605 +++++++++++++++++----------- src/drivers/ps2/ps2_uart.c | 385 ++++++++++-------- 2 files changed, 586 insertions(+), 404 deletions(-) diff --git a/src/drivers/input/input_mouse_ps2.c b/src/drivers/input/input_mouse_ps2.c index ddb4286..e3b4848 100644 --- a/src/drivers/input/input_mouse_ps2.c +++ b/src/drivers/input/input_mouse_ps2.c @@ -159,6 +159,7 @@ typedef enum { struct zmk_mouse_ps2_config { const struct device *ps2_device; + bool has_rst_gpio; struct gpio_dt_spec rst_gpio; int rst_gpio_port_num; @@ -199,6 +200,9 @@ struct zmk_mouse_ps2_data { int packet_idx; struct zmk_mouse_ps2_packet prev_packet; struct k_work_delayable packet_buffer_timeout; +#if IS_ENABLED(CONFIG_SETTINGS) + struct k_work_delayable zmk_mouse_ps2_save_work; +#endif bool button_l_is_held; bool button_m_is_held; @@ -215,72 +219,17 @@ struct zmk_mouse_ps2_data { uint8_t tp_neg_inertia; uint8_t tp_value6; uint8_t tp_pts_threshold; -}; -static const struct zmk_mouse_ps2_config zmk_mouse_ps2_config = { - .ps2_device = DEVICE_DT_GET(DT_INST_PHANDLE(0, ps2_device)), - -#if DT_INST_NODE_HAS_PROP(0, rst_gpios) - .rst_gpio = GPIO_DT_SPEC_INST_GET(0, rst_gpios), - .rst_gpio_port_num = DT_PROP(DT_INST_PHANDLE(0, rst_gpios), port), -#else - .rst_gpio = - { - .port = NULL, - .pin = 0, - .dt_flags = 0, - }, - .rst_gpio_port_num = 0, -#endif - - .scroll_mode = DT_INST_PROP_OR(0, scroll_mode, false), - .disable_clicking = DT_INST_PROP_OR(0, disable_clicking, false), - .sampling_rate = DT_INST_PROP_OR(0, sampling_rate, MOUSE_PS2_CMD_SET_SAMPLING_RATE_DEFAULT), - .tp_press_to_select = DT_INST_PROP_OR(0, tp_press_to_select, false), - .tp_press_to_select_threshold = DT_INST_PROP_OR(0, tp_press_to_select_threshold, -1), - .tp_sensitivity = DT_INST_PROP_OR(0, tp_sensitivity, -1), - .tp_neg_inertia = DT_INST_PROP_OR(0, tp_neg_inertia, -1), - .tp_val6_upper_speed = DT_INST_PROP_OR(0, tp_val6_upper_speed, -1), - .tp_x_invert = DT_INST_PROP_OR(0, tp_x_invert, false), - .tp_y_invert = DT_INST_PROP_OR(0, tp_y_invert, false), - .tp_xy_swap = DT_INST_PROP_OR(0, tp_xy_swap, false), + void *activity_callback; + void *activity_resend_callback; }; -static struct zmk_mouse_ps2_data zmk_mouse_ps2_data = { - .packet_mode = MOUSE_PS2_PACKET_MODE_PS2_DEFAULT, - .packet_idx = 0, - .prev_packet = - { - .button_l = false, - .button_r = false, - .button_m = false, - .overflow_x = 0, - .overflow_y = 0, - .mov_x = 0, - .mov_y = 0, - .scroll = 0, - }, - - .button_l_is_held = false, - .button_m_is_held = false, - .button_r_is_held = false, - - // Data reporting is disabled on init - .activity_reporting_on = false, - - // Device Info - .is_trackpoint = false, - .manufacturer_id = 0x0, - .secondary_id = 0x0, - .rom_id = 0x0, - - // PS2 devices initialize with this rate - .sampling_rate = MOUSE_PS2_CMD_SET_SAMPLING_RATE_DEFAULT, - .tp_sensitivity = MOUSE_PS2_CMD_TP_SET_SENSITIVITY_DEFAULT, - .tp_neg_inertia = MOUSE_PS2_CMD_TP_SET_NEG_INERTIA_DEFAULT, - .tp_value6 = MOUSE_PS2_CMD_TP_SET_VALUE6_UPPER_PLATEAU_SPEED_DEFAULT, - .tp_pts_threshold = MOUSE_PS2_CMD_TP_SET_PTS_THRESHOLD_DEFAULT, -}; +// declare datas and configs for all devices +// NOTES: Settings will be assigned to all devices via exposed api from behaviors +#define ZMK_PS2_MOUSE_DEFINE_DATA_N_CFG(n) \ + static struct zmk_mouse_ps2_data data##n; \ + static const struct zmk_mouse_ps2_config config##n; +DT_INST_FOREACH_STATUS_OKAY(ZMK_PS2_MOUSE_DEFINE_DATA_N_CFG) static int allowed_sampling_rates[] = { 10, 20, 40, 60, 80, 100, 200, @@ -303,23 +252,26 @@ int zmk_mouse_ps2_settings_save(); * Mouse Activity Packet Reading */ -void zmk_mouse_ps2_activity_process_cmd(zmk_mouse_ps2_packet_mode packet_mode, uint8_t packet_state, +void zmk_mouse_ps2_activity_process_cmd(const struct device *dev, + zmk_mouse_ps2_packet_mode packet_mode, uint8_t packet_state, uint8_t packet_x, uint8_t packet_y, uint8_t packet_extra); -void zmk_mouse_ps2_activity_abort_cmd(); -void zmk_mouse_ps2_activity_move_mouse(int16_t mov_x, int16_t mov_y); -void zmk_mouse_ps2_activity_scroll(int8_t scroll_y); -void zmk_mouse_ps2_activity_click_buttons(bool button_l, bool button_m, bool button_r); -void zmk_mouse_ps2_activity_reset_packet_buffer(); +void zmk_mouse_ps2_activity_abort_cmd(const struct device *dev, char *reason); +void zmk_mouse_ps2_activity_move_mouse(const struct device *dev, int16_t mov_x, int16_t mov_y); +void zmk_mouse_ps2_activity_scroll(const struct device *dev, int8_t scroll_y); +void zmk_mouse_ps2_activity_click_buttons(const struct device *dev, + bool button_l, bool button_m, bool button_r); +void zmk_mouse_ps2_activity_reset_packet_buffer(const struct device *dev); + struct zmk_mouse_ps2_packet zmk_mouse_ps2_activity_parse_packet_buffer(zmk_mouse_ps2_packet_mode packet_mode, uint8_t packet_state, uint8_t packet_x, uint8_t packet_y, uint8_t packet_extra); -void zmk_mouse_ps2_activity_toggle_layer(); // Called by the PS/2 driver whenver the mouse sends a byte and // reporting is enabled through `zmk_mouse_ps2_activity_reporting_enable`. -void zmk_mouse_ps2_activity_callback(const struct device *ps2_device, uint8_t byte) { - struct zmk_mouse_ps2_data *data = &zmk_mouse_ps2_data; +void zmk_mouse_ps2_activity_callback(const struct device *dev, + const struct device *ps2_device, uint8_t byte) { + struct zmk_mouse_ps2_data *data = dev->data; k_work_cancel_delayable(&data->packet_buffer_timeout); @@ -336,7 +288,7 @@ void zmk_mouse_ps2_activity_callback(const struct device *ps2_device, uint8_t by int alignment_bit = MOUSE_PS2_GET_BIT(byte, 3); if (alignment_bit != 1) { - zmk_mouse_ps2_activity_abort_cmd("Bit 3 of packet is 0 instead of 1"); + zmk_mouse_ps2_activity_abort_cmd(data->dev, "Bit 3 of packet is 0 instead of 1"); return; } } else if (data->packet_idx == 1) { @@ -344,10 +296,11 @@ void zmk_mouse_ps2_activity_callback(const struct device *ps2_device, uint8_t by } else if ((data->packet_mode == MOUSE_PS2_PACKET_MODE_PS2_DEFAULT && data->packet_idx == 2) || (data->packet_mode == MOUSE_PS2_PACKET_MODE_SCROLL && data->packet_idx == 3)) { - zmk_mouse_ps2_activity_process_cmd(data->packet_mode, data->packet_buffer[0], + zmk_mouse_ps2_activity_process_cmd(data->dev, + data->packet_mode, data->packet_buffer[0], data->packet_buffer[1], data->packet_buffer[2], data->packet_buffer[3]); - zmk_mouse_ps2_activity_reset_packet_buffer(); + zmk_mouse_ps2_activity_reset_packet_buffer(data->dev); return; } @@ -356,9 +309,9 @@ void zmk_mouse_ps2_activity_callback(const struct device *ps2_device, uint8_t by k_work_schedule(&data->packet_buffer_timeout, MOUSE_PS2_TIMEOUT_ACTIVITY_PACKET); } -void zmk_mouse_ps2_activity_abort_cmd(char *reason) { - struct zmk_mouse_ps2_data *data = &zmk_mouse_ps2_data; - const struct zmk_mouse_ps2_config *config = &zmk_mouse_ps2_config; +void zmk_mouse_ps2_activity_abort_cmd(const struct device *dev, char *reason) { + struct zmk_mouse_ps2_data *data = dev->data; + const struct zmk_mouse_ps2_config *config = dev->config; const struct device *ps2_device = config->ps2_device; LOG_ERR("PS/2 Mouse cmd buffer is out of aligment. Requesting resend: %s", reason); @@ -366,48 +319,56 @@ void zmk_mouse_ps2_activity_abort_cmd(char *reason) { data->packet_idx = 0; ps2_write(ps2_device, MOUSE_PS2_CMD_RESEND[0]); - zmk_mouse_ps2_activity_reset_packet_buffer(); + zmk_mouse_ps2_activity_reset_packet_buffer(dev); } -#if IS_ENABLED(CONFIG_ZMK_INPUT_MOUSE_PS2_ENABLE_PS2_RESEND_CALLBACK) - // Called if the PS/2 driver encounters a transmission error and asks the // device to resend the packet. // The device will resend all bytes of the packet. So we need to reset our // buffer. -void zmk_mouse_ps2_activity_resend_callback(const struct device *ps2_device) { - struct zmk_mouse_ps2_data *data = &zmk_mouse_ps2_data; +void zmk_mouse_ps2_activity_resend_callback(const struct device *dev, + const struct device *ps2_device) { + +#if IS_ENABLED(CONFIG_ZMK_INPUT_MOUSE_PS2_ENABLE_PS2_RESEND_CALLBACK) + + struct zmk_mouse_ps2_data *data = dev->data; LOG_WRN("Mouse movement cmd had transmission error on idx=%d", data->packet_idx); - zmk_mouse_ps2_activity_reset_packet_buffer(); -} + zmk_mouse_ps2_activity_reset_packet_buffer(dev); #endif /* IS_ENABLED(CONFIG_ZMK_INPUT_MOUSE_PS2_ENABLE_PS2_RESEND_CALLBACK) */ +} // Called if no new byte arrives within // MOUSE_PS2_TIMEOUT_ACTIVITY_PACKET void zmk_mouse_ps2_activity_packet_timout(struct k_work *item) { - struct zmk_mouse_ps2_data *data = &zmk_mouse_ps2_data; + + struct k_work_delayable *work_delayable = (struct k_work_delayable *)item; + struct zmk_mouse_ps2_data *data = CONTAINER_OF(work_delayable, + struct zmk_mouse_ps2_data, + packet_buffer_timeout); + const struct device *dev = data->dev; LOG_DBG("Mouse movement cmd timed out on idx=%d", data->packet_idx); // Reset the cmd buffer in case we are out of alignment. // This way if the mouse ever gets out of alignment, the user // can reset it by just not moving it for a second. - zmk_mouse_ps2_activity_reset_packet_buffer(); + zmk_mouse_ps2_activity_reset_packet_buffer(dev); } -void zmk_mouse_ps2_activity_reset_packet_buffer() { - struct zmk_mouse_ps2_data *data = &zmk_mouse_ps2_data; +void zmk_mouse_ps2_activity_reset_packet_buffer(const struct device *dev) { + struct zmk_mouse_ps2_data *data = dev->data; data->packet_idx = 0; memset(data->packet_buffer, 0x0, sizeof(data->packet_buffer)); } -void zmk_mouse_ps2_activity_process_cmd(zmk_mouse_ps2_packet_mode packet_mode, uint8_t packet_state, +void zmk_mouse_ps2_activity_process_cmd(const struct device *dev, + zmk_mouse_ps2_packet_mode packet_mode, uint8_t packet_state, uint8_t packet_x, uint8_t packet_y, uint8_t packet_extra) { - struct zmk_mouse_ps2_data *data = &zmk_mouse_ps2_data; + struct zmk_mouse_ps2_data *data = dev->data; struct zmk_mouse_ps2_packet packet; packet = zmk_mouse_ps2_activity_parse_packet_buffer(packet_mode, packet_state, packet_x, packet_y, packet_extra); @@ -427,7 +388,7 @@ void zmk_mouse_ps2_activity_process_cmd(zmk_mouse_ps2_packet_mode packet_mode, u LOG_WRN("Detected overflow in both x and y. " "Probably mistransmission. Aborting..."); - zmk_mouse_ps2_activity_abort_cmd("Overflow in both x and y"); + zmk_mouse_ps2_activity_abort_cmd(data->dev, "Overflow in both x and y"); return; } @@ -442,13 +403,13 @@ void zmk_mouse_ps2_activity_process_cmd(zmk_mouse_ps2_packet_mode packet_mode, u "x_delta=%d, y_delta=%d)", packet.mov_x, packet.mov_y, packet.overflow_x, packet.overflow_y, packet.scroll, packet.button_l, packet.button_m, packet.button_r, x_delta, y_delta); - zmk_mouse_ps2_activity_abort_cmd("Exceeds movement threshold."); + zmk_mouse_ps2_activity_abort_cmd(data->dev, "Exceeds movement threshold."); return; } #endif - zmk_mouse_ps2_activity_move_mouse(packet.mov_x, packet.mov_y); - zmk_mouse_ps2_activity_click_buttons(packet.button_l, packet.button_m, packet.button_r); + zmk_mouse_ps2_activity_move_mouse(data->dev, packet.mov_x, packet.mov_y); + zmk_mouse_ps2_activity_click_buttons(data->dev, packet.button_l, packet.button_m, packet.button_r); data->prev_packet = packet; } @@ -509,8 +470,8 @@ zmk_mouse_ps2_activity_parse_packet_buffer(zmk_mouse_ps2_packet_mode packet_mode static bool zmk_mouse_ps2_is_non_zero_1d_movement(int16_t speed) { return speed != 0; } -void zmk_mouse_ps2_activity_move_mouse(int16_t mov_x, int16_t mov_y) { - struct zmk_mouse_ps2_data *data = &zmk_mouse_ps2_data; +void zmk_mouse_ps2_activity_move_mouse(const struct device *dev, int16_t mov_x, int16_t mov_y) { + struct zmk_mouse_ps2_data *data = dev->data; int ret = 0; bool have_x = zmk_mouse_ps2_is_non_zero_1d_movement(mov_x); @@ -557,9 +518,10 @@ void zmk_mouse_ps2_activity_move_mouse(int16_t mov_x, int16_t mov_y) { } -void zmk_mouse_ps2_activity_click_buttons(bool button_l, bool button_m, bool button_r) { - struct zmk_mouse_ps2_data *data = &zmk_mouse_ps2_data; - const struct zmk_mouse_ps2_config *config = &zmk_mouse_ps2_config; +void zmk_mouse_ps2_activity_click_buttons(const struct device *dev, + bool button_l, bool button_m, bool button_r) { + struct zmk_mouse_ps2_data *data = dev->data; + const struct zmk_mouse_ps2_config *config = dev->config; // TODO: Integrate this with the proper button mask instead // of hardcoding the mouse button indeces. @@ -618,7 +580,7 @@ void zmk_mouse_ps2_activity_click_buttons(bool button_l, bool button_m, bool but "Probably tranmission error.", buttons_pressed, buttons_released); - zmk_mouse_ps2_activity_abort_cmd("Multiple button presses"); + zmk_mouse_ps2_activity_abort_cmd(dev, "Multiple button presses"); return; } @@ -677,8 +639,8 @@ void zmk_mouse_ps2_activity_click_buttons(bool button_l, bool button_m, bool but /* * PS/2 Command Sending Wrapper */ -int zmk_mouse_ps2_activity_reporting_enable(); -int zmk_mouse_ps2_activity_reporting_disable(); +int zmk_mouse_ps2_activity_reporting_enable(const struct device *dev); +int zmk_mouse_ps2_activity_reporting_disable(const struct device *dev); struct zmk_mouse_ps2_send_cmd_resp { int err; @@ -687,10 +649,11 @@ struct zmk_mouse_ps2_send_cmd_resp { int resp_len; }; -struct zmk_mouse_ps2_send_cmd_resp zmk_mouse_ps2_send_cmd(char *cmd, int cmd_len, uint8_t *arg, +struct zmk_mouse_ps2_send_cmd_resp zmk_mouse_ps2_send_cmd(const struct device *dev, + char *cmd, int cmd_len, uint8_t *arg, int resp_len, bool pause_reporting) { - struct zmk_mouse_ps2_data *data = &zmk_mouse_ps2_data; - const struct zmk_mouse_ps2_config *config = &zmk_mouse_ps2_config; + struct zmk_mouse_ps2_data *data = dev->data; + const struct zmk_mouse_ps2_config *config = dev->config; const struct device *ps2_device = config->ps2_device; int err = 0; bool prev_activity_reporting_on = data->activity_reporting_on; @@ -723,7 +686,7 @@ struct zmk_mouse_ps2_send_cmd_resp zmk_mouse_ps2_send_cmd(char *cmd, int cmd_len if (pause_reporting == true && data->activity_reporting_on == true) { LOG_DBG("Disabling mouse activity reporting..."); - resp.err = zmk_mouse_ps2_activity_reporting_disable(); + resp.err = zmk_mouse_ps2_activity_reporting_disable(dev); if (resp.err) { snprintf(resp.err_msg, sizeof(resp.err_msg), "Could not disable data reporting (%d)", err); @@ -766,7 +729,7 @@ struct zmk_mouse_ps2_send_cmd_resp zmk_mouse_ps2_send_cmd(char *cmd, int cmd_len if (pause_reporting == true && prev_activity_reporting_on == true) { LOG_DBG("Enabling mouse activity reporting..."); - err = zmk_mouse_ps2_activity_reporting_enable(); + err = zmk_mouse_ps2_activity_reporting_enable(dev); if (err) { // Don' overwrite existing error if (resp.err == 0) { @@ -780,9 +743,9 @@ struct zmk_mouse_ps2_send_cmd_resp zmk_mouse_ps2_send_cmd(char *cmd, int cmd_len return resp; } -int zmk_mouse_ps2_activity_reporting_enable() { - struct zmk_mouse_ps2_data *data = &zmk_mouse_ps2_data; - const struct zmk_mouse_ps2_config *config = &zmk_mouse_ps2_config; +int zmk_mouse_ps2_activity_reporting_enable(const struct device *dev) { + struct zmk_mouse_ps2_data *data = dev->data; + const struct zmk_mouse_ps2_config *config = dev->config; const struct device *ps2_device = config->ps2_device; if (data->activity_reporting_on == true) { @@ -807,9 +770,9 @@ int zmk_mouse_ps2_activity_reporting_enable() { return 0; } -int zmk_mouse_ps2_activity_reporting_disable() { - struct zmk_mouse_ps2_data *data = &zmk_mouse_ps2_data; - const struct zmk_mouse_ps2_config *config = &zmk_mouse_ps2_config; +int zmk_mouse_ps2_activity_reporting_disable(const struct device *dev) { + struct zmk_mouse_ps2_data *data = dev->data; + const struct zmk_mouse_ps2_config *config = dev->config; const struct device *ps2_device = config->ps2_device; if (data->activity_reporting_on == false) { @@ -882,9 +845,10 @@ int zmk_mouse_ps2_array_get_prev_elem(int elem, int *array, size_t array_size) { * PS/2 Commands */ -int zmk_mouse_ps2_reset(const struct device *ps2_device) { +int zmk_mouse_ps2_reset(const struct device *dev, const struct device *ps2_device) { struct zmk_mouse_ps2_send_cmd_resp resp = - zmk_mouse_ps2_send_cmd(MOUSE_PS2_CMD_RESET, sizeof(MOUSE_PS2_CMD_RESET), NULL, + zmk_mouse_ps2_send_cmd(dev, + MOUSE_PS2_CMD_RESET, sizeof(MOUSE_PS2_CMD_RESET), NULL, MOUSE_PS2_CMD_RESET_RESP_LEN, false); if (resp.err) { LOG_ERR("Could not send reset cmd"); @@ -893,8 +857,8 @@ int zmk_mouse_ps2_reset(const struct device *ps2_device) { return resp.err; } -int zmk_mouse_ps2_set_sampling_rate(uint8_t sampling_rate) { - struct zmk_mouse_ps2_data *data = &zmk_mouse_ps2_data; +int zmk_mouse_ps2_set_sampling_rate(const struct device *dev, uint8_t sampling_rate) { + struct zmk_mouse_ps2_data *data = dev->data; int rate_idx = zmk_mouse_ps2_array_get_elem_index(sampling_rate, allowed_sampling_rates, sizeof(allowed_sampling_rates)); @@ -904,6 +868,7 @@ int zmk_mouse_ps2_set_sampling_rate(uint8_t sampling_rate) { } struct zmk_mouse_ps2_send_cmd_resp resp = zmk_mouse_ps2_send_cmd( + dev, MOUSE_PS2_CMD_SET_SAMPLING_RATE, sizeof(MOUSE_PS2_CMD_SET_SAMPLING_RATE), &sampling_rate, MOUSE_PS2_CMD_SET_SAMPLING_RATE_RESP_LEN, true); if (resp.err) { @@ -918,8 +883,9 @@ int zmk_mouse_ps2_set_sampling_rate(uint8_t sampling_rate) { return resp.err; } -int zmk_mouse_ps2_get_device_id(uint8_t *device_id) { +int zmk_mouse_ps2_get_device_id(const struct device *dev, uint8_t *device_id) { struct zmk_mouse_ps2_send_cmd_resp resp = zmk_mouse_ps2_send_cmd( + dev, MOUSE_PS2_CMD_GET_DEVICE_ID, sizeof(MOUSE_PS2_CMD_GET_DEVICE_ID), NULL, 1, true); if (resp.err) { LOG_ERR("Could not get device id"); @@ -931,8 +897,8 @@ int zmk_mouse_ps2_get_device_id(uint8_t *device_id) { return 0; } -int zmk_mouse_ps2_set_packet_mode(zmk_mouse_ps2_packet_mode mode) { - struct zmk_mouse_ps2_data *data = &zmk_mouse_ps2_data; +int zmk_mouse_ps2_set_packet_mode(const struct device *dev, zmk_mouse_ps2_packet_mode mode) { + struct zmk_mouse_ps2_data *data = dev->data; if (mode == MOUSE_PS2_PACKET_MODE_PS2_DEFAULT) { // Do nothing. Mouse devices enable this by @@ -941,16 +907,16 @@ int zmk_mouse_ps2_set_packet_mode(zmk_mouse_ps2_packet_mode mode) { } bool prev_activity_reporting_on = data->activity_reporting_on; - zmk_mouse_ps2_activity_reporting_disable(); + zmk_mouse_ps2_activity_reporting_disable(dev); // Setting a mouse mode is a bit like using a cheat code // in a video game. // You have to send a specific sequence of sampling rates. if (mode == MOUSE_PS2_PACKET_MODE_SCROLL) { - zmk_mouse_ps2_set_sampling_rate(200); - zmk_mouse_ps2_set_sampling_rate(100); - zmk_mouse_ps2_set_sampling_rate(80); + zmk_mouse_ps2_set_sampling_rate(dev, 200); + zmk_mouse_ps2_set_sampling_rate(dev, 100); + zmk_mouse_ps2_set_sampling_rate(dev, 80); } // Scroll mouse + 5 buttons mode can be enabled with the @@ -958,13 +924,13 @@ int zmk_mouse_ps2_set_packet_mode(zmk_mouse_ps2_packet_mode mode) { // test it, I am commenting it out for now. // else if(mode == MOUSE_PS2_PACKET_MODE_SCROLL_5_BUTTONS) { - // zmk_mouse_ps2_set_sampling_rate(200); - // zmk_mouse_ps2_set_sampling_rate(200); - // zmk_mouse_ps2_set_sampling_rate(80); + // zmk_mouse_ps2_set_sampling_rate(dev, 200); + // zmk_mouse_ps2_set_sampling_rate(dev, 200); + // zmk_mouse_ps2_set_sampling_rate(dev, 80); // } uint8_t device_id; - int err = zmk_mouse_ps2_get_device_id(&device_id); + int err = zmk_mouse_ps2_get_device_id(dev, &device_id); if (err) { LOG_ERR("Could not enable packet mode %d. Failed to get device id with " "error %d", @@ -1005,10 +971,10 @@ int zmk_mouse_ps2_set_packet_mode(zmk_mouse_ps2_packet_mode mode) { } // Restore sampling rate to prev value - zmk_mouse_ps2_set_sampling_rate(data->sampling_rate); + zmk_mouse_ps2_set_sampling_rate(dev, data->sampling_rate); if (prev_activity_reporting_on == true) { - zmk_mouse_ps2_activity_reporting_enable(); + zmk_mouse_ps2_activity_reporting_enable(dev); } return err; @@ -1018,8 +984,10 @@ int zmk_mouse_ps2_set_packet_mode(zmk_mouse_ps2_packet_mode mode) { * Trackpoint Commands */ -int zmk_mouse_ps2_tp_get_secondary_id(uint8_t *manufacturer_id, uint8_t *secondary_id) { +int zmk_mouse_ps2_tp_get_secondary_id(const struct device *dev, + uint8_t *manufacturer_id, uint8_t *secondary_id) { struct zmk_mouse_ps2_send_cmd_resp resp = zmk_mouse_ps2_send_cmd( + dev, MOUSE_PS2_CMD_TP_GET_SECONDARY_ID, sizeof(MOUSE_PS2_CMD_TP_GET_SECONDARY_ID), NULL, MOUSE_PS2_CMD_TP_GET_SECONDARY_ID_RESP_LEN, true); if (resp.err) { @@ -1033,9 +1001,10 @@ int zmk_mouse_ps2_tp_get_secondary_id(uint8_t *manufacturer_id, uint8_t *seconda return 0; } -int zmk_mouse_ps2_tp_get_rom_id(uint8_t *rom_id) { +int zmk_mouse_ps2_tp_get_rom_id(const struct device *dev, uint8_t *rom_id) { struct zmk_mouse_ps2_send_cmd_resp resp = - zmk_mouse_ps2_send_cmd(MOUSE_PS2_CMD_TP_GET_ROM_ID, sizeof(MOUSE_PS2_CMD_TP_GET_ROM_ID), + zmk_mouse_ps2_send_cmd(dev, + MOUSE_PS2_CMD_TP_GET_ROM_ID, sizeof(MOUSE_PS2_CMD_TP_GET_ROM_ID), NULL, MOUSE_PS2_CMD_TP_GET_ROM_ID_RESP_LEN, true); if (resp.err) { LOG_ERR("Could not get secondary id"); @@ -1075,11 +1044,12 @@ char *zmk_mouse_ps2_get_manufacturer_str(uint8_t manufacturer_id) { // trackpoints. After that they started to use other manufacturers. // // Page 19 of the IBM TP spec describes the features of different firmware ids. -int zmk_mouse_ps2_tp_get_device_info(bool *is_tp, uint8_t *tp_manufacturer_id, +int zmk_mouse_ps2_tp_get_device_info(const struct device *dev, + bool *is_tp, uint8_t *tp_manufacturer_id, uint8_t *tp_secondary_id, uint8_t *tp_rom_id, char *device_str, int device_str_size) { - int err = zmk_mouse_ps2_tp_get_secondary_id(tp_manufacturer_id, tp_secondary_id); + int err = zmk_mouse_ps2_tp_get_secondary_id(dev, tp_manufacturer_id, tp_secondary_id); if (err) { // Only TPs implement this command. So, if it fails, it means the // device is not a TP. @@ -1096,7 +1066,7 @@ int zmk_mouse_ps2_tp_get_device_info(bool *is_tp, uint8_t *tp_manufacturer_id, *is_tp = true; - err = zmk_mouse_ps2_tp_get_rom_id(tp_rom_id); + err = zmk_mouse_ps2_tp_get_rom_id(dev, tp_rom_id); if (err) { LOG_ERR("Could not determine TP rom id: %d", err); *tp_rom_id = 0x0; @@ -1112,8 +1082,9 @@ int zmk_mouse_ps2_tp_get_device_info(bool *is_tp, uint8_t *tp_manufacturer_id, return err; } -int zmk_mouse_ps2_tp_get_config_byte(uint8_t *config_byte) { +int zmk_mouse_ps2_tp_get_config_byte(const struct device* dev, uint8_t *config_byte) { struct zmk_mouse_ps2_send_cmd_resp resp = zmk_mouse_ps2_send_cmd( + dev, MOUSE_PS2_CMD_TP_GET_CONFIG_BYTE, sizeof(MOUSE_PS2_CMD_TP_GET_CONFIG_BYTE), NULL, MOUSE_PS2_CMD_TP_GET_CONFIG_BYTE_RESP_LEN, true); if (resp.err) { @@ -1126,9 +1097,10 @@ int zmk_mouse_ps2_tp_get_config_byte(uint8_t *config_byte) { return 0; } -int zmk_mouse_ps2_tp_set_config_option(int config_bit, bool enabled, char *descr) { +int zmk_mouse_ps2_tp_set_config_option(const struct device *dev, + int config_bit, bool enabled, char *descr) { uint8_t config_byte; - int err = zmk_mouse_ps2_tp_get_config_byte(&config_byte); + int err = zmk_mouse_ps2_tp_get_config_byte(dev, &config_byte); if (err) { return err; } @@ -1146,6 +1118,7 @@ int zmk_mouse_ps2_tp_set_config_option(int config_bit, bool enabled, char *descr MOUSE_PS2_SET_BIT(config_byte, enabled, config_bit); struct zmk_mouse_ps2_send_cmd_resp resp = zmk_mouse_ps2_send_cmd( + dev, MOUSE_PS2_CMD_TP_SET_CONFIG_BYTE, sizeof(MOUSE_PS2_CMD_TP_SET_CONFIG_BYTE), &config_byte, MOUSE_PS2_CMD_TP_SET_CONFIG_BYTE_RESP_LEN, true); if (resp.err) { @@ -1158,36 +1131,41 @@ int zmk_mouse_ps2_tp_set_config_option(int config_bit, bool enabled, char *descr return 0; } -int zmk_mouse_ps2_tp_press_to_select_set(bool enabled) { - int err = zmk_mouse_ps2_tp_set_config_option(MOUSE_PS2_TP_CONFIG_BIT_PRESS_TO_SELECT, enabled, +int zmk_mouse_ps2_tp_press_to_select_set(const struct device *dev, bool enabled) { + int err = zmk_mouse_ps2_tp_set_config_option(dev, + MOUSE_PS2_TP_CONFIG_BIT_PRESS_TO_SELECT, enabled, "Press To Select"); return err; } -int zmk_mouse_ps2_tp_invert_x_set(bool enabled) { - int err = - zmk_mouse_ps2_tp_set_config_option(MOUSE_PS2_TP_CONFIG_BIT_INVERT_X, enabled, "Invert X"); +int zmk_mouse_ps2_tp_invert_x_set(const struct device *dev, bool enabled) { + int err = zmk_mouse_ps2_tp_set_config_option(dev, + MOUSE_PS2_TP_CONFIG_BIT_INVERT_X, enabled, + "Invert X"); return err; } -int zmk_mouse_ps2_tp_invert_y_set(bool enabled) { - int err = - zmk_mouse_ps2_tp_set_config_option(MOUSE_PS2_TP_CONFIG_BIT_INVERT_Y, enabled, "Invert Y"); +int zmk_mouse_ps2_tp_invert_y_set(const struct device *dev, bool enabled) { + int err = zmk_mouse_ps2_tp_set_config_option(dev, + MOUSE_PS2_TP_CONFIG_BIT_INVERT_Y, enabled, + "Invert Y"); return err; } -int zmk_mouse_ps2_tp_swap_xy_set(bool enabled) { - int err = - zmk_mouse_ps2_tp_set_config_option(MOUSE_PS2_TP_CONFIG_BIT_SWAP_XY, enabled, "Swap XY"); +int zmk_mouse_ps2_tp_swap_xy_set(const struct device *dev, bool enabled) { + int err = zmk_mouse_ps2_tp_set_config_option(dev, + MOUSE_PS2_TP_CONFIG_BIT_SWAP_XY, enabled, + "Swap XY"); return err; } -int zmk_mouse_ps2_tp_sensitivity_get(uint8_t *sensitivity) { +int zmk_mouse_ps2_tp_sensitivity_get(const struct device *dev, uint8_t *sensitivity) { struct zmk_mouse_ps2_send_cmd_resp resp = zmk_mouse_ps2_send_cmd( + dev, MOUSE_PS2_CMD_TP_GET_SENSITIVITY, sizeof(MOUSE_PS2_CMD_TP_GET_SENSITIVITY), NULL, MOUSE_PS2_CMD_TP_GET_SENSITIVITY_RESP_LEN, true); if (resp.err) { @@ -1205,8 +1183,8 @@ int zmk_mouse_ps2_tp_sensitivity_get(uint8_t *sensitivity) { return 0; } -int zmk_mouse_ps2_tp_sensitivity_set(int sensitivity) { - struct zmk_mouse_ps2_data *data = &zmk_mouse_ps2_data; +int zmk_mouse_ps2_tp_sensitivity_set(const struct device *dev, int sensitivity) { + struct zmk_mouse_ps2_data *data = dev->data; if (sensitivity < MOUSE_PS2_CMD_TP_SET_SENSITIVITY_MIN || sensitivity > MOUSE_PS2_CMD_TP_SET_SENSITIVITY_MAX) { @@ -1218,6 +1196,7 @@ int zmk_mouse_ps2_tp_sensitivity_set(int sensitivity) { uint8_t arg = sensitivity; struct zmk_mouse_ps2_send_cmd_resp resp = zmk_mouse_ps2_send_cmd( + dev, MOUSE_PS2_CMD_TP_SET_SENSITIVITY, sizeof(MOUSE_PS2_CMD_TP_SET_SENSITIVITY), &arg, MOUSE_PS2_CMD_TP_SET_SENSITIVITY_RESP_LEN, true); if (resp.err) { @@ -1232,23 +1211,32 @@ int zmk_mouse_ps2_tp_sensitivity_set(int sensitivity) { return 0; } -int zmk_mouse_ps2_tp_sensitivity_change(int amount) { - struct zmk_mouse_ps2_data *data = &zmk_mouse_ps2_data; +int zmk_mouse_ps2_tp_sensitivity_change_dev(const struct device *dev, int amount) { + struct zmk_mouse_ps2_data *data = dev->data; int new_val = data->tp_sensitivity + amount; LOG_INF("Setting trackpoint sensitivity to %d", new_val); - int err = zmk_mouse_ps2_tp_sensitivity_set(new_val); + int err = zmk_mouse_ps2_tp_sensitivity_set(dev, new_val); if (err == 0) { - - zmk_mouse_ps2_settings_save(); + zmk_mouse_ps2_settings_save(dev); } return err; } -int zmk_mouse_ps2_tp_negative_inertia_get(uint8_t *neg_inertia) { +int zmk_mouse_ps2_tp_sensitivity_change(int amount) { + + #define ZMK_PS2_MOUSE_DEFINE_SETTINGS_SEN_CHG_DEV(n) \ + zmk_mouse_ps2_tp_sensitivity_change_dev(data##n.dev, amount); + DT_INST_FOREACH_STATUS_OKAY(ZMK_PS2_MOUSE_DEFINE_SETTINGS_SEN_CHG_DEV) + + return 0; +} + +int zmk_mouse_ps2_tp_negative_inertia_get(const struct device *dev, uint8_t *neg_inertia) { struct zmk_mouse_ps2_send_cmd_resp resp = zmk_mouse_ps2_send_cmd( + dev, MOUSE_PS2_CMD_TP_GET_NEG_INERTIA, sizeof(MOUSE_PS2_CMD_TP_GET_NEG_INERTIA), NULL, MOUSE_PS2_CMD_TP_GET_NEG_INERTIA_RESP_LEN, true); if (resp.err) { @@ -1264,8 +1252,8 @@ int zmk_mouse_ps2_tp_negative_inertia_get(uint8_t *neg_inertia) { return 0; } -int zmk_mouse_ps2_tp_neg_inertia_set(int neg_inertia) { - struct zmk_mouse_ps2_data *data = &zmk_mouse_ps2_data; +int zmk_mouse_ps2_tp_neg_inertia_set(const struct device *dev, int neg_inertia) { + struct zmk_mouse_ps2_data *data = dev->data; if (neg_inertia < MOUSE_PS2_CMD_TP_SET_NEG_INERTIA_MIN || neg_inertia > MOUSE_PS2_CMD_TP_SET_NEG_INERTIA_MAX) { @@ -1277,6 +1265,7 @@ int zmk_mouse_ps2_tp_neg_inertia_set(int neg_inertia) { uint8_t arg = neg_inertia; struct zmk_mouse_ps2_send_cmd_resp resp = zmk_mouse_ps2_send_cmd( + dev, MOUSE_PS2_CMD_TP_SET_NEG_INERTIA, sizeof(MOUSE_PS2_CMD_TP_SET_NEG_INERTIA), &arg, MOUSE_PS2_CMD_TP_SET_NEG_INERTIA_RESP_LEN, true); if (resp.err) { @@ -1291,24 +1280,33 @@ int zmk_mouse_ps2_tp_neg_inertia_set(int neg_inertia) { return 0; } -int zmk_mouse_ps2_tp_neg_inertia_change(int amount) { - struct zmk_mouse_ps2_data *data = &zmk_mouse_ps2_data; +int zmk_mouse_ps2_tp_neg_inertia_change_dev(const struct device *dev, int amount) { + struct zmk_mouse_ps2_data *data = dev->data; int new_val = data->tp_neg_inertia + amount; LOG_INF("Setting negative inertia to %d", new_val); - int err = zmk_mouse_ps2_tp_neg_inertia_set(new_val); + int err = zmk_mouse_ps2_tp_neg_inertia_set(dev, new_val); if (err == 0) { - - zmk_mouse_ps2_settings_save(); + zmk_mouse_ps2_settings_save(dev); } return err; } -int zmk_mouse_ps2_tp_value6_upper_plateau_speed_get(uint8_t *value6) { +int zmk_mouse_ps2_tp_neg_inertia_change(int amount) { + + #define ZMK_PS2_MOUSE_DEFINE_NEG_INERTIA_CHG_DEV(n) \ + zmk_mouse_ps2_tp_neg_inertia_change_dev(data##n.dev, amount); + DT_INST_FOREACH_STATUS_OKAY(ZMK_PS2_MOUSE_DEFINE_NEG_INERTIA_CHG_DEV) + + return 0; +} + +int zmk_mouse_ps2_tp_value6_upper_plateau_speed_get(const struct device *dev, uint8_t *value6) { struct zmk_mouse_ps2_send_cmd_resp resp = - zmk_mouse_ps2_send_cmd(MOUSE_PS2_CMD_TP_GET_VALUE6_UPPER_PLATEAU_SPEED, + zmk_mouse_ps2_send_cmd(dev, + MOUSE_PS2_CMD_TP_GET_VALUE6_UPPER_PLATEAU_SPEED, sizeof(MOUSE_PS2_CMD_TP_GET_VALUE6_UPPER_PLATEAU_SPEED), NULL, MOUSE_PS2_CMD_TP_GET_VALUE6_UPPER_PLATEAU_SPEED_RESP_LEN, true); if (resp.err) { @@ -1324,8 +1322,8 @@ int zmk_mouse_ps2_tp_value6_upper_plateau_speed_get(uint8_t *value6) { return 0; } -int zmk_mouse_ps2_tp_value6_upper_plateau_speed_set(int value6) { - struct zmk_mouse_ps2_data *data = &zmk_mouse_ps2_data; +int zmk_mouse_ps2_tp_value6_upper_plateau_speed_set(const struct device *dev, int value6) { + struct zmk_mouse_ps2_data *data = dev->data; if (value6 < MOUSE_PS2_CMD_TP_SET_VALUE6_UPPER_PLATEAU_SPEED_MIN || value6 > MOUSE_PS2_CMD_TP_SET_VALUE6_UPPER_PLATEAU_SPEED_MAX) { @@ -1338,7 +1336,8 @@ int zmk_mouse_ps2_tp_value6_upper_plateau_speed_set(int value6) { uint8_t arg = value6; struct zmk_mouse_ps2_send_cmd_resp resp = - zmk_mouse_ps2_send_cmd(MOUSE_PS2_CMD_TP_SET_VALUE6_UPPER_PLATEAU_SPEED, + zmk_mouse_ps2_send_cmd(dev, + MOUSE_PS2_CMD_TP_SET_VALUE6_UPPER_PLATEAU_SPEED, sizeof(MOUSE_PS2_CMD_TP_SET_VALUE6_UPPER_PLATEAU_SPEED), &arg, MOUSE_PS2_CMD_TP_SET_VALUE6_UPPER_PLATEAU_SPEED_RESP_LEN, true); if (resp.err) { @@ -1353,23 +1352,32 @@ int zmk_mouse_ps2_tp_value6_upper_plateau_speed_set(int value6) { return 0; } -int zmk_mouse_ps2_tp_value6_upper_plateau_speed_change(int amount) { - struct zmk_mouse_ps2_data *data = &zmk_mouse_ps2_data; +int zmk_mouse_ps2_tp_value6_upper_plateau_speed_change_dev(const struct device *dev, int amount) { + struct zmk_mouse_ps2_data *data = dev->data; int new_val = data->tp_value6 + amount; LOG_INF("Setting value6 upper plateau speed to %d", new_val); - int err = zmk_mouse_ps2_tp_value6_upper_plateau_speed_set(new_val); + int err = zmk_mouse_ps2_tp_value6_upper_plateau_speed_set(dev, new_val); if (err == 0) { - - zmk_mouse_ps2_settings_save(); + zmk_mouse_ps2_settings_save(dev); } return err; } -int zmk_mouse_ps2_tp_pts_threshold_get(uint8_t *pts_threshold) { +int zmk_mouse_ps2_tp_value6_upper_plateau_speed_change(int amount) { + + #define ZMK_PS2_MOUSE_DEFINE_VALUE6_CHG_DEV(n) \ + zmk_mouse_ps2_tp_value6_upper_plateau_speed_change_dev(data##n.dev, amount); + DT_INST_FOREACH_STATUS_OKAY(ZMK_PS2_MOUSE_DEFINE_VALUE6_CHG_DEV) + + return 0; +} + +int zmk_mouse_ps2_tp_pts_threshold_get(const struct device *dev, uint8_t *pts_threshold) { struct zmk_mouse_ps2_send_cmd_resp resp = zmk_mouse_ps2_send_cmd( + dev, MOUSE_PS2_CMD_TP_GET_PTS_THRESHOLD, sizeof(MOUSE_PS2_CMD_TP_GET_PTS_THRESHOLD), NULL, MOUSE_PS2_CMD_TP_GET_PTS_THRESHOLD_RESP_LEN, true); if (resp.err) { @@ -1385,8 +1393,8 @@ int zmk_mouse_ps2_tp_pts_threshold_get(uint8_t *pts_threshold) { return 0; } -int zmk_mouse_ps2_tp_pts_threshold_set(int pts_threshold) { - struct zmk_mouse_ps2_data *data = &zmk_mouse_ps2_data; +int zmk_mouse_ps2_tp_pts_threshold_set(const struct device *dev, int pts_threshold) { + struct zmk_mouse_ps2_data *data = dev->data; if (pts_threshold < MOUSE_PS2_CMD_TP_SET_PTS_THRESHOLD_MIN || pts_threshold > MOUSE_PS2_CMD_TP_SET_PTS_THRESHOLD_MAX) { @@ -1398,6 +1406,7 @@ int zmk_mouse_ps2_tp_pts_threshold_set(int pts_threshold) { uint8_t arg = pts_threshold; struct zmk_mouse_ps2_send_cmd_resp resp = zmk_mouse_ps2_send_cmd( + dev, MOUSE_PS2_CMD_TP_SET_PTS_THRESHOLD, sizeof(MOUSE_PS2_CMD_TP_SET_PTS_THRESHOLD), &arg, MOUSE_PS2_CMD_TP_SET_PTS_THRESHOLD_RESP_LEN, true); if (resp.err) { @@ -1412,29 +1421,34 @@ int zmk_mouse_ps2_tp_pts_threshold_set(int pts_threshold) { return 0; } -int zmk_mouse_ps2_tp_pts_threshold_change(int amount) { - struct zmk_mouse_ps2_data *data = &zmk_mouse_ps2_data; +int zmk_mouse_ps2_tp_pts_threshold_change_dev(const struct device *dev, int amount) { + struct zmk_mouse_ps2_data *data = dev->data; int new_val = data->tp_pts_threshold + amount; LOG_INF("Setting press-to-select threshold to %d", new_val); - int err = zmk_mouse_ps2_tp_pts_threshold_set(new_val); + int err = zmk_mouse_ps2_tp_pts_threshold_set(dev, new_val); if (err == 0) { - - zmk_mouse_ps2_settings_save(); + zmk_mouse_ps2_settings_save(dev); } return err; } +int zmk_mouse_ps2_tp_pts_threshold_change(int amount) { + + #define ZMK_PS2_MOUSE_DEFINE_PTS_THRESHOLD_CHG_DEV(n) \ + zmk_mouse_ps2_tp_pts_threshold_change_dev(data##n.dev, amount); + DT_INST_FOREACH_STATUS_OKAY(ZMK_PS2_MOUSE_DEFINE_PTS_THRESHOLD_CHG_DEV) + + return 0; +} /* * State Saving */ #if IS_ENABLED(CONFIG_SETTINGS) -struct k_work_delayable zmk_mouse_ps2_save_work; - int zmk_mouse_ps2_settings_save_setting(char *setting_name, const void *value, size_t val_len) { char setting_path[40]; snprintf(setting_path, sizeof(setting_path), "%s/%s", MOUSE_PS2_SETTINGS_SUBTREE, setting_name); @@ -1462,7 +1476,12 @@ int zmk_mouse_ps2_settings_reset_setting(char *setting_name) { } static void zmk_mouse_ps2_settings_save_work(struct k_work *work) { - struct zmk_mouse_ps2_data *data = &zmk_mouse_ps2_data; + + struct k_work_delayable *work_delayable = (struct k_work_delayable *)work; + struct zmk_mouse_ps2_data *data = CONTAINER_OF(work_delayable, + struct zmk_mouse_ps2_data, + zmk_mouse_ps2_save_work); + // const struct device *dev = data->dev; LOG_INF("Saving PS/2 Mouse Settings."); @@ -1477,19 +1496,20 @@ static void zmk_mouse_ps2_settings_save_work(struct k_work *work) { } #endif -int zmk_mouse_ps2_settings_save() { +int zmk_mouse_ps2_settings_save(const struct device *dev) { LOG_DBG(""); + struct zmk_mouse_ps2_data *data = dev->data; #if IS_ENABLED(CONFIG_SETTINGS) int ret = - k_work_reschedule(&zmk_mouse_ps2_save_work, K_MSEC(CONFIG_ZMK_SETTINGS_SAVE_DEBOUNCE)); + k_work_reschedule(&data->zmk_mouse_ps2_save_work, K_MSEC(CONFIG_ZMK_SETTINGS_SAVE_DEBOUNCE)); return MIN(ret, 0); #else return 0; #endif } -int zmk_mouse_ps2_settings_reset() { +int zmk_mouse_ps2_settings_reset_dev(const struct device *dev) { LOG_INF("Deleting runtime settings..."); zmk_mouse_ps2_settings_reset_setting(MOUSE_PS2_ST_TP_SENSITIVITY); @@ -1498,20 +1518,30 @@ int zmk_mouse_ps2_settings_reset() { zmk_mouse_ps2_settings_reset_setting(MOUSE_PS2_ST_TP_PTS_THRESHOLD); LOG_INF("Restoring default settings to TP.."); - zmk_mouse_ps2_tp_sensitivity_set(MOUSE_PS2_CMD_TP_SET_SENSITIVITY_DEFAULT); + zmk_mouse_ps2_tp_sensitivity_set(dev, MOUSE_PS2_CMD_TP_SET_SENSITIVITY_DEFAULT); - zmk_mouse_ps2_tp_neg_inertia_set(MOUSE_PS2_CMD_TP_SET_NEG_INERTIA_DEFAULT); + zmk_mouse_ps2_tp_neg_inertia_set(dev, MOUSE_PS2_CMD_TP_SET_NEG_INERTIA_DEFAULT); zmk_mouse_ps2_tp_value6_upper_plateau_speed_set( + dev, MOUSE_PS2_CMD_TP_SET_VALUE6_UPPER_PLATEAU_SPEED_DEFAULT); - zmk_mouse_ps2_tp_pts_threshold_set(MOUSE_PS2_CMD_TP_SET_PTS_THRESHOLD_DEFAULT); + zmk_mouse_ps2_tp_pts_threshold_set(dev, MOUSE_PS2_CMD_TP_SET_PTS_THRESHOLD_DEFAULT); return 0; } -int zmk_mouse_ps2_settings_log() { - struct zmk_mouse_ps2_data *data = &zmk_mouse_ps2_data; +int zmk_mouse_ps2_settings_reset() { + + #define ZMK_PS2_MOUSE_DEFINE_SETTINGS_RESET_DEV(n) \ + zmk_mouse_ps2_settings_reset_dev(data##n.dev); + DT_INST_FOREACH_STATUS_OKAY(ZMK_PS2_MOUSE_DEFINE_SETTINGS_RESET_DEV) + + return 0; +} + +int zmk_mouse_ps2_settings_log_dev(const struct device *dev) { + struct zmk_mouse_ps2_data *data = dev->data; char settings_str[250]; @@ -1529,13 +1559,23 @@ int zmk_mouse_ps2_settings_log() { return 0; } +int zmk_mouse_ps2_settings_log() { + + #define ZMK_PS2_MOUSE_DEFINE_SETTINGS_LOG_DEV(n) \ + zmk_mouse_ps2_settings_log_dev(data##n.dev); + DT_INST_FOREACH_STATUS_OKAY(ZMK_PS2_MOUSE_DEFINE_SETTINGS_LOG_DEV) + + return 0; +} + // This function is called when settings are loaded from flash by // `settings_load_subtree`. // It's called once for each PS/2 mouse setting that has been stored. -static int zmk_mouse_ps2_settings_restore(const char *name, size_t len, settings_read_cb read_cb, - void *cb_arg) { - struct zmk_mouse_ps2_data *data = &zmk_mouse_ps2_data; - const struct zmk_mouse_ps2_config *config = &zmk_mouse_ps2_config; +static int zmk_mouse_ps2_settings_restore_dev(const struct device *dev, + const char *name, size_t len, settings_read_cb read_cb, + void *cb_arg) { + struct zmk_mouse_ps2_data *data = dev->data; + const struct zmk_mouse_ps2_config *config = dev->config; uint8_t setting_val; @@ -1569,7 +1609,7 @@ static int zmk_mouse_ps2_settings_restore(const char *name, size_t len, settings return 0; } - return zmk_mouse_ps2_tp_sensitivity_set(setting_val); + return zmk_mouse_ps2_tp_sensitivity_set(dev, setting_val); } else if (strcmp(name, MOUSE_PS2_ST_TP_NEG_INERTIA) == 0) { if (config->tp_neg_inertia != -1) { LOG_WRN("Not restoring runtime settings for %s with value %d, because deviceconfig " @@ -1579,7 +1619,7 @@ static int zmk_mouse_ps2_settings_restore(const char *name, size_t len, settings return 0; } - return zmk_mouse_ps2_tp_neg_inertia_set(setting_val); + return zmk_mouse_ps2_tp_neg_inertia_set(dev, setting_val); } else if (strcmp(name, MOUSE_PS2_ST_TP_VALUE6) == 0) { if (config->tp_val6_upper_speed != -1) { LOG_WRN("Not restoring runtime settings for %s with value %d, because deviceconfig " @@ -1589,7 +1629,7 @@ static int zmk_mouse_ps2_settings_restore(const char *name, size_t len, settings return 0; } - return zmk_mouse_ps2_tp_value6_upper_plateau_speed_set(setting_val); + return zmk_mouse_ps2_tp_value6_upper_plateau_speed_set(dev, setting_val); } else if (strcmp(name, MOUSE_PS2_ST_TP_PTS_THRESHOLD) == 0) { if (config->tp_press_to_select_threshold != -1) { LOG_WRN("Not restoring runtime settings for %s with value %d, because deviceconfig " @@ -1599,20 +1639,31 @@ static int zmk_mouse_ps2_settings_restore(const char *name, size_t len, settings return 0; } - return zmk_mouse_ps2_tp_pts_threshold_set(setting_val); + return zmk_mouse_ps2_tp_pts_threshold_set(dev, setting_val); } return -EINVAL; } +static int zmk_mouse_ps2_settings_restore(const char *name, size_t len, settings_read_cb read_cb, + void *cb_arg) { + + #define ZMK_PS2_MOUSE_DEFINE_SETTINGS_RESTORE_DEV(n) \ + zmk_mouse_ps2_settings_restore_dev(data##n.dev, name, len, read_cb, cb_arg); + DT_INST_FOREACH_STATUS_OKAY(ZMK_PS2_MOUSE_DEFINE_SETTINGS_RESTORE_DEV) + + return -EINVAL; +} + struct settings_handler zmk_mouse_ps2_settings_conf = { .name = MOUSE_PS2_SETTINGS_SUBTREE, .h_set = zmk_mouse_ps2_settings_restore, }; -int zmk_mouse_ps2_settings_init() { +int zmk_mouse_ps2_settings_init(const struct device *dev) { #if IS_ENABLED(CONFIG_SETTINGS) LOG_DBG(""); + struct zmk_mouse_ps2_data *data = dev->data; settings_subsys_init(); @@ -1622,7 +1673,7 @@ int zmk_mouse_ps2_settings_init() { return err; } - k_work_init_delayable(&zmk_mouse_ps2_save_work, zmk_mouse_ps2_settings_save_work); + k_work_init_delayable(&data->zmk_mouse_ps2_save_work, zmk_mouse_ps2_settings_save_work); // This will load the settings and then call // `zmk_mouse_ps2_settings_restore`, which will set the settings @@ -1633,18 +1684,22 @@ int zmk_mouse_ps2_settings_init() { } /* - * Init + * Init PS2 mouse */ static void zmk_mouse_ps2_init_thread(int dev_ptr, int unused); -int zmk_mouse_ps2_init_power_on_reset(); +int zmk_mouse_ps2_init_power_on_reset(const struct device *dev); int zmk_mouse_ps2_init_wait_for_mouse(const struct device *dev); static int zmk_mouse_ps2_init(const struct device *dev) { + struct zmk_mouse_ps2_data *data = dev->data; + // const struct zmk_mouse_ps2_config *config = dev->config; + LOG_DBG("Inside zmk_mouse_ps2_init"); + data->dev = dev; LOG_DBG("Creating mouse_ps2 init thread."); - k_thread_create(&zmk_mouse_ps2_data.thread, zmk_mouse_ps2_data.thread_stack, + k_thread_create(&data->thread, data->thread_stack, MOUSE_PS2_THREAD_STACK_SIZE, (k_thread_entry_t)zmk_mouse_ps2_init_thread, (struct device *)dev, 0, NULL, K_PRIO_COOP(MOUSE_PS2_THREAD_PRIORITY), 0, K_MSEC(ZMK_MOUSE_PS2_INIT_THREAD_DELAY_MS)); @@ -1653,17 +1708,15 @@ static int zmk_mouse_ps2_init(const struct device *dev) { } static void zmk_mouse_ps2_init_thread(int dev_ptr, int unused) { - struct zmk_mouse_ps2_data *data = &zmk_mouse_ps2_data; int err; + const struct device *dev = INT_TO_POINTER(dev_ptr); + struct zmk_mouse_ps2_data *data = dev->data; + const struct zmk_mouse_ps2_config *config = dev->config; - data->dev = INT_TO_POINTER(dev_ptr); - - const struct zmk_mouse_ps2_config *config = data->dev->config; - - zmk_mouse_ps2_init_power_on_reset(); + zmk_mouse_ps2_init_power_on_reset(dev); LOG_INF("Waiting for mouse to connect..."); - err = zmk_mouse_ps2_init_wait_for_mouse(data->dev); + err = zmk_mouse_ps2_init_wait_for_mouse(dev); if (err) { LOG_ERR("Could not init a mouse in %d attempts. Giving up. " "Power cycle the mouse and reset zmk to try again.", @@ -1674,7 +1727,7 @@ static void zmk_mouse_ps2_init_thread(int dev_ptr, int unused) { if (config->sampling_rate != MOUSE_PS2_CMD_SET_SAMPLING_RATE_DEFAULT) { LOG_INF("Setting sample rate to %d...", config->sampling_rate); - zmk_mouse_ps2_set_sampling_rate(config->sampling_rate); + zmk_mouse_ps2_set_sampling_rate(dev, config->sampling_rate); if (err) { LOG_ERR("Could not set sampling rate to %d: %d", config->sampling_rate, err); return; @@ -1682,7 +1735,8 @@ static void zmk_mouse_ps2_init_thread(int dev_ptr, int unused) { } char device_descr[64] = "undetermined device"; - zmk_mouse_ps2_tp_get_device_info(&data->is_trackpoint, &data->manufacturer_id, + zmk_mouse_ps2_tp_get_device_info(dev, + &data->is_trackpoint, &data->manufacturer_id, &data->secondary_id, &data->rom_id, device_descr, sizeof(device_descr)); @@ -1692,62 +1746,62 @@ static void zmk_mouse_ps2_init_thread(int dev_ptr, int unused) { if (config->tp_press_to_select) { LOG_INF("Enabling TP press to select..."); - zmk_mouse_ps2_tp_press_to_select_set(true); + zmk_mouse_ps2_tp_press_to_select_set(dev, true); } if (config->tp_press_to_select_threshold != -1) { LOG_INF("Setting TP press to select thereshold to %d...", config->tp_press_to_select_threshold); - zmk_mouse_ps2_tp_pts_threshold_set(config->tp_press_to_select_threshold); + zmk_mouse_ps2_tp_pts_threshold_set(dev, config->tp_press_to_select_threshold); } if (config->tp_sensitivity != -1) { LOG_INF("Setting TP sensitivity to %d...", config->tp_sensitivity); - zmk_mouse_ps2_tp_sensitivity_set(config->tp_sensitivity); + zmk_mouse_ps2_tp_sensitivity_set(dev, config->tp_sensitivity); } if (config->tp_neg_inertia != -1) { LOG_INF("Setting TP inertia to %d...", config->tp_neg_inertia); - zmk_mouse_ps2_tp_neg_inertia_set(config->tp_neg_inertia); + zmk_mouse_ps2_tp_neg_inertia_set(dev, config->tp_neg_inertia); } if (config->tp_val6_upper_speed != -1) { LOG_INF("Setting TP value 6 upper speed plateau to %d...", config->tp_val6_upper_speed); - zmk_mouse_ps2_tp_value6_upper_plateau_speed_set(config->tp_val6_upper_speed); + zmk_mouse_ps2_tp_value6_upper_plateau_speed_set(dev, config->tp_val6_upper_speed); } if (config->tp_x_invert) { LOG_INF("Inverting trackpoint x axis."); - zmk_mouse_ps2_tp_invert_x_set(true); + zmk_mouse_ps2_tp_invert_x_set(dev, true); } if (config->tp_y_invert) { LOG_INF("Inverting trackpoint y axis."); - zmk_mouse_ps2_tp_invert_y_set(true); + zmk_mouse_ps2_tp_invert_y_set(dev, true); } if (config->tp_xy_swap) { LOG_INF("Swapping trackpoint x and y axis."); - zmk_mouse_ps2_tp_swap_xy_set(true); + zmk_mouse_ps2_tp_swap_xy_set(dev, true); } } if (config->scroll_mode) { LOG_INF("Enabling scroll mode."); - zmk_mouse_ps2_set_packet_mode(MOUSE_PS2_PACKET_MODE_SCROLL); + zmk_mouse_ps2_set_packet_mode(dev, MOUSE_PS2_PACKET_MODE_SCROLL); } - zmk_mouse_ps2_settings_init(); + zmk_mouse_ps2_settings_init(dev); // Configure read callback LOG_DBG("Configuring ps2 callback..."); #if IS_ENABLED(CONFIG_ZMK_INPUT_MOUSE_PS2_ENABLE_PS2_RESEND_CALLBACK) - err = ps2_config(config->ps2_device, &zmk_mouse_ps2_activity_callback, - &zmk_mouse_ps2_activity_resend_callback); + err = ps2_config(config->ps2_device, data->activity_callback, + data->activity_resend_callback); #else - err = ps2_config(config->ps2_device, &zmk_mouse_ps2_activity_callback); + err = ps2_config(config->ps2_device, data->activity_callback); #endif /* IS_ENABLED(CONFIG_ZMK_INPUT_MOUSE_PS2_ENABLE_PS2_RESEND_CALLBACK) */ @@ -1757,7 +1811,7 @@ static void zmk_mouse_ps2_init_thread(int dev_ptr, int unused) { } LOG_INF("Enabling data reporting and ps2 callback..."); - err = zmk_mouse_ps2_activity_reporting_enable(); + err = zmk_mouse_ps2_activity_reporting_enable(dev); if (err) { LOG_ERR("Could not activate ps2 callback: %d", err); } else { @@ -1777,9 +1831,9 @@ static void zmk_mouse_ps2_init_thread(int dev_ptr, int unused) { // the time power is applied to the TrackPoint controller. Activity on the // clock and data lines is ignored prior to the completion of the diagnostic // sequence. (See RESET mode of operation.)" -int zmk_mouse_ps2_init_power_on_reset() { - struct zmk_mouse_ps2_data *data = &zmk_mouse_ps2_data; - const struct zmk_mouse_ps2_config *config = &zmk_mouse_ps2_config; +int zmk_mouse_ps2_init_power_on_reset(const struct device *dev) { + struct zmk_mouse_ps2_data *data = dev->data; + const struct zmk_mouse_ps2_config *config = dev->config; // Check if the optional rst-gpios setting was set if (config->rst_gpio.port == NULL) { @@ -1841,7 +1895,7 @@ int zmk_mouse_ps2_init_wait_for_mouse(const struct device *dev) { LOG_WRN("Got invalid PS/2 self-test result: 0x%x", read_val); LOG_INF("Trying to reset PS2 device..."); - zmk_mouse_ps2_reset(config->ps2_device); + zmk_mouse_ps2_reset(dev, config->ps2_device); continue; } @@ -1871,7 +1925,7 @@ int zmk_mouse_ps2_init_wait_for_mouse(const struct device *dev) { // So we try sending the reset command. if (i % 2 == 0) { LOG_INF("Trying to reset PS2 device..."); - zmk_mouse_ps2_reset(config->ps2_device); + zmk_mouse_ps2_reset(dev, config->ps2_device); continue; } @@ -1881,8 +1935,81 @@ int zmk_mouse_ps2_init_wait_for_mouse(const struct device *dev) { return 1; } + +// Define wrapper function declaration for zmk_mouse_ps2_activity*_callback +// will assign to zmk_mouse_ps2_data in below +#define PS2_MOUSE_CALLBACK_DEFINE(n) \ + void zmk_mouse_ps2_activity_callback##n(const struct device *ps2_device, uint8_t byte); \ + void zmk_mouse_ps2_activity_resend_callback##n(const struct device *ps2_device); + +DT_INST_FOREACH_STATUS_OKAY(PS2_MOUSE_CALLBACK_DEFINE) + + // Depends on the UART and PS2 init priorities, which are 55 and 45 by default #define ZMK_MOUSE_PS2_INIT_PRIORITY 90 -DEVICE_DT_INST_DEFINE(0, &zmk_mouse_ps2_init, NULL, &zmk_mouse_ps2_data, &zmk_mouse_ps2_config, - POST_KERNEL, ZMK_MOUSE_PS2_INIT_PRIORITY, NULL); +#define ZMK_PS2_MOUSE_DEFINE(n) \ + static struct zmk_mouse_ps2_data data##n = { \ + .packet_mode = MOUSE_PS2_PACKET_MODE_PS2_DEFAULT, \ + .packet_idx = 0, \ + .prev_packet = { \ + .button_l = false, .button_r = false, .button_m = false, \ + .overflow_x = 0, .overflow_y = 0, .mov_x = 0, .mov_y = 0, .scroll = 0, \ + }, \ + .button_l_is_held = false, \ + .button_m_is_held = false, \ + .button_r_is_held = false, \ + .activity_reporting_on = false, \ + .is_trackpoint = false, \ + .manufacturer_id = 0x0, \ + .secondary_id = 0x0, \ + .rom_id = 0x0, \ + .sampling_rate = MOUSE_PS2_CMD_SET_SAMPLING_RATE_DEFAULT, \ + .tp_sensitivity = MOUSE_PS2_CMD_TP_SET_SENSITIVITY_DEFAULT, \ + .tp_neg_inertia = MOUSE_PS2_CMD_TP_SET_NEG_INERTIA_DEFAULT, \ + .tp_value6 = MOUSE_PS2_CMD_TP_SET_VALUE6_UPPER_PLATEAU_SPEED_DEFAULT, \ + .tp_pts_threshold = MOUSE_PS2_CMD_TP_SET_PTS_THRESHOLD_DEFAULT, \ + .activity_callback = &zmk_mouse_ps2_activity_callback##n, \ + .activity_resend_callback = &zmk_mouse_ps2_activity_resend_callback##n, \ + }; \ + static const struct zmk_mouse_ps2_config config##n = { \ + .ps2_device = DEVICE_DT_GET(DT_INST_PHANDLE(n, ps2_device)), \ + .has_rst_gpio = DT_INST_NODE_HAS_PROP(n, rst_gpio), \ + .rst_gpio = COND_CODE_1( \ + DT_INST_NODE_HAS_PROP(n, rst_gpio), \ + (GPIO_DT_SPEC_INST_GET(n, rst_gpios)), \ + ({ .port = NULL, .pin = 0, .dt_flags = 0, })), \ + .rst_gpio_port_num = COND_CODE_1( \ + DT_INST_NODE_HAS_PROP(n, rst_gpio), \ + (DT_PROP(DT_INST_PHANDLE(n, rst_gpios), port)), \ + (0)), \ + .scroll_mode = DT_INST_PROP_OR(n, scroll_mode, false), \ + .disable_clicking = DT_INST_PROP_OR(n, disable_clicking, false), \ + .sampling_rate = DT_INST_PROP_OR(n, sampling_rate, \ + MOUSE_PS2_CMD_SET_SAMPLING_RATE_DEFAULT), \ + .tp_press_to_select = DT_INST_PROP_OR(n, tp_press_to_select, false), \ + .tp_press_to_select_threshold = DT_INST_PROP_OR(n, tp_press_to_select_threshold, -1), \ + .tp_sensitivity = DT_INST_PROP_OR(n, tp_sensitivity, -1), \ + .tp_neg_inertia = DT_INST_PROP_OR(n, tp_neg_inertia, -1), \ + .tp_val6_upper_speed = DT_INST_PROP_OR(n, tp_val6_upper_speed, -1), \ + .tp_x_invert = DT_INST_PROP_OR(n, tp_x_invert, false), \ + .tp_y_invert = DT_INST_PROP_OR(n, tp_y_invert, false), \ + .tp_xy_swap = DT_INST_PROP_OR(n, tp_xy_swap, false), \ + }; \ + DEVICE_DT_INST_DEFINE(0, &zmk_mouse_ps2_init, NULL, &data##n, &config##n, \ + POST_KERNEL, ZMK_MOUSE_PS2_INIT_PRIORITY, NULL); + +DT_INST_FOREACH_STATUS_OKAY(ZMK_PS2_MOUSE_DEFINE) + + +// Define wrapper function implementation for zmk_mouse_ps2_activity*_callback +// assigned to zmk_mouse_ps2_data on above +#define PS2_MOUSE_CALLBACK_IMPL_DEFINE(n) \ + void zmk_mouse_ps2_activity_callback##n(const struct device *ps2_device, uint8_t byte) { \ + zmk_mouse_ps2_activity_callback(data##n.dev, ps2_device, byte); \ + } \ + void zmk_mouse_ps2_activity_resend_callback##n(const struct device *ps2_device) { \ + zmk_mouse_ps2_activity_resend_callback(data##n.dev, ps2_device); \ + } + +DT_INST_FOREACH_STATUS_OKAY(PS2_MOUSE_CALLBACK_IMPL_DEFINE) diff --git a/src/drivers/ps2/ps2_uart.c b/src/drivers/ps2/ps2_uart.c index a0a2286..2aeecf7 100644 --- a/src/drivers/ps2/ps2_uart.c +++ b/src/drivers/ps2/ps2_uart.c @@ -186,33 +186,9 @@ struct ps2_uart_data { struct k_work_delayable write_scl_timout; struct k_work resend_cmd_work; -}; - -static const struct ps2_uart_config ps2_uart_config = { - .uart_dev = DEVICE_DT_GET(DT_INST_BUS(0)), - .scl_gpio = GPIO_DT_SPEC_INST_GET(0, scl_gpios), - .sda_gpio = GPIO_DT_SPEC_INST_GET(0, sda_gpios), - .pcfg = PINCTRL_DT_DEV_CONFIG_GET(DT_INST_BUS(0)), - .scl_gpio_port_num = DT_PROP(DT_INST_PHANDLE(0, scl_gpios), port), - .sda_gpio_port_num = DT_PROP(DT_INST_PHANDLE(0, sda_gpios), port), -}; - -static struct ps2_uart_data ps2_uart_data = { - .callback_byte = 0x0, - .callback_isr = NULL, - -#if IS_ENABLED(CONFIG_PS2_UART_ENABLE_PS2_RESEND_CALLBACK) - .resend_callback_isr = NULL, -#endif /* IS_ENABLED(CONFIG_PS2_UART_ENABLE_PS2_RESEND_CALLBACK) */ - - .callback_enabled = false, - - .cur_write_status = PS2_UART_WRITE_STATUS_INACTIVE, - .cur_write_byte = 0x0, - .cur_write_pos = 0, - .write_awaits_resp = false, - .write_awaits_resp_byte = 0x0, + void *scl_rupt_async; + void *scl_rupt_blocking; }; K_THREAD_STACK_DEFINE(ps2_uart_work_queue_stack_area, PS2_UART_WORK_QUEUE_STACK_SIZE); @@ -225,7 +201,7 @@ static struct k_work_q ps2_uart_work_queue_cb; * Function Definitions */ -int ps2_uart_write_byte(uint8_t byte); +int ps2_uart_write_byte(const struct device *dev, uint8_t byte); /* * Helpers functions @@ -233,35 +209,35 @@ int ps2_uart_write_byte(uint8_t byte); #define PS2_UART_GET_BIT(data, bit_pos) ((data >> bit_pos) & 0x1) -int ps2_uart_get_scl() { - const struct ps2_uart_config *config = &ps2_uart_config; +int ps2_uart_get_scl(const struct device *dev) { + const struct ps2_uart_config *config = dev->config; int rc = gpio_pin_get_dt(&config->scl_gpio); return rc; } -int ps2_uart_get_sda() { - const struct ps2_uart_config *config = &ps2_uart_config; +int ps2_uart_get_sda(const struct device *dev) { + const struct ps2_uart_config *config = dev->config; int rc = gpio_pin_get_dt(&config->sda_gpio); return rc; } -void ps2_uart_set_scl(int state) { - const struct ps2_uart_config *config = &ps2_uart_config; +void ps2_uart_set_scl(const struct device *dev, int state) { + const struct ps2_uart_config *config = dev->config; gpio_pin_set_dt(&config->scl_gpio, state); } -void ps2_uart_set_sda(int state) { - const struct ps2_uart_config *config = &ps2_uart_config; +void ps2_uart_set_sda(const struct device *dev, int state) { + const struct ps2_uart_config *config = dev->config; // LOG_INF("Seting sda to %d", state); gpio_pin_set_dt(&config->sda_gpio, state); } -int ps2_uart_configure_pin_scl(gpio_flags_t flags, char *descr) { - struct ps2_uart_config *config = (struct ps2_uart_config *)&ps2_uart_config; +int ps2_uart_configure_pin_scl(const struct device *dev, gpio_flags_t flags, char *descr) { + const struct ps2_uart_config *config = dev->config; int err; err = gpio_pin_configure_dt(&config->scl_gpio, flags); @@ -272,14 +248,16 @@ int ps2_uart_configure_pin_scl(gpio_flags_t flags, char *descr) { return err; } -int ps2_uart_configure_pin_scl_input() { return ps2_uart_configure_pin_scl((GPIO_INPUT), "input"); } +int ps2_uart_configure_pin_scl_input(const struct device *dev) { + return ps2_uart_configure_pin_scl(dev, (GPIO_INPUT), "input"); +} -int ps2_uart_configure_pin_scl_output() { - return ps2_uart_configure_pin_scl((GPIO_OUTPUT_HIGH), "output"); +int ps2_uart_configure_pin_scl_output(const struct device *dev) { + return ps2_uart_configure_pin_scl(dev, (GPIO_OUTPUT_HIGH), "output"); } -int ps2_uart_configure_pin_sda(gpio_flags_t flags, char *descr) { - struct ps2_uart_config *config = (struct ps2_uart_config *)&ps2_uart_config; +int ps2_uart_configure_pin_sda(const struct device *dev, gpio_flags_t flags, char *descr) { + const struct ps2_uart_config *config = dev->config; int err; err = gpio_pin_configure_dt(&config->sda_gpio, flags); @@ -290,14 +268,16 @@ int ps2_uart_configure_pin_sda(gpio_flags_t flags, char *descr) { return err; } -int ps2_uart_configure_pin_sda_input() { return ps2_uart_configure_pin_sda((GPIO_INPUT), "input"); } +int ps2_uart_configure_pin_sda_input(const struct device *dev) { + return ps2_uart_configure_pin_sda(dev, (GPIO_INPUT), "input"); +} -int ps2_uart_configure_pin_sda_output() { - return ps2_uart_configure_pin_sda((GPIO_OUTPUT_HIGH), "output"); +int ps2_uart_configure_pin_sda_output(const struct device *dev) { + return ps2_uart_configure_pin_sda(dev, (GPIO_OUTPUT_HIGH), "output"); } -int ps2_uart_set_scl_callback_enabled(bool enabled) { - struct ps2_uart_config *config = (struct ps2_uart_config *)&ps2_uart_config; +int ps2_uart_set_scl_callback_enabled(const struct device *dev, bool enabled) { + const struct ps2_uart_config *config = dev->config; int err; // LOG_INF("Setting ps2_uart_set_scl_callback_enabled: %d", enabled); @@ -323,8 +303,8 @@ int ps2_uart_set_scl_callback_enabled(bool enabled) { return err; } -static int ps2_uart_set_mode_read() { - const struct ps2_uart_config *config = &ps2_uart_config; +static int ps2_uart_set_mode_read(const struct device *dev) { + const struct ps2_uart_config *config = dev->config; int err; // Set the SDA pin for the uart device @@ -335,7 +315,7 @@ static int ps2_uart_set_mode_read() { } // Make sure SCL interrupt is disabled - ps2_uart_set_scl_callback_enabled(false); + ps2_uart_set_scl_callback_enabled(dev, false); // Enable UART interrupt uart_irq_rx_enable(config->uart_dev); @@ -343,8 +323,8 @@ static int ps2_uart_set_mode_read() { return err; } -static int ps2_uart_set_mode_write() { - const struct ps2_uart_config *config = &ps2_uart_config; +static int ps2_uart_set_mode_write(const struct device *dev) { + const struct ps2_uart_config *config = dev->config; int err; // Set pincntrl with unused pins so that we can control the pins @@ -361,9 +341,9 @@ static int ps2_uart_set_mode_write() { uart_irq_rx_disable(config->uart_dev); // Configure data and clock lines for output - ps2_uart_set_scl_callback_enabled(false); - ps2_uart_configure_pin_scl_output(); - ps2_uart_configure_pin_sda_output(); + ps2_uart_set_scl_callback_enabled(dev, false); + ps2_uart_configure_pin_scl_output(dev); + ps2_uart_configure_pin_sda_output(dev); return err; } @@ -388,8 +368,8 @@ bool ps2_uart_get_byte_parity(uint8_t byte) { return !byte_parity; } -uint8_t ps2_uart_data_queue_get_next(uint8_t *dst_byte, k_timeout_t timeout) { - struct ps2_uart_data *data = &ps2_uart_data; +uint8_t ps2_uart_data_queue_get_next(const struct device *dev, uint8_t *dst_byte, k_timeout_t timeout) { + struct ps2_uart_data *data = dev->data; struct ps2_uart_data_queue_item queue_data; int ret; @@ -404,14 +384,14 @@ uint8_t ps2_uart_data_queue_get_next(uint8_t *dst_byte, k_timeout_t timeout) { return 0; } -void ps2_uart_data_queue_empty() { - struct ps2_uart_data *data = &ps2_uart_data; +void ps2_uart_data_queue_empty(const struct device *dev) { + struct ps2_uart_data *data = dev->data; k_msgq_purge(&data->data_queue); } -void ps2_uart_data_queue_add(uint8_t byte) { - struct ps2_uart_data *data = &ps2_uart_data; +void ps2_uart_data_queue_add(const struct device *dev, uint8_t byte) { + struct ps2_uart_data *data = dev->data; int ret; @@ -428,7 +408,7 @@ void ps2_uart_data_queue_add(uint8_t byte) { LOG_WRN("Data queue full. Removing oldest item."); uint8_t tmp_byte; - ps2_uart_data_queue_get_next(&tmp_byte, K_NO_WAIT); + ps2_uart_data_queue_get_next(dev, &tmp_byte, K_NO_WAIT); } } @@ -439,9 +419,13 @@ void ps2_uart_data_queue_add(uint8_t byte) { void ps2_uart_send_cmd_resend_worker(struct k_work *item) { -#if IS_ENABLED(CONFIG_PS2_UART_ENABLE_PS2_RESEND_CALLBACK) + // struct k_work_delayable *work_delayable = (struct k_work_delayable *)work; + struct ps2_uart_data *data = CONTAINER_OF(item, + struct ps2_uart_data, + resend_cmd_work); + const struct device *dev = data->dev; - struct ps2_uart_data *data = &ps2_uart_data; +#if IS_ENABLED(CONFIG_PS2_UART_ENABLE_PS2_RESEND_CALLBACK) // Notify the PS/2 device driver that we are requesting a resend. // PS/2 devices don't just resend the last byte that was sent, but the @@ -455,11 +439,11 @@ void ps2_uart_send_cmd_resend_worker(struct k_work *item) { uint8_t cmd = 0xfe; // LOG_DBG("Requesting resend of data with command: 0x%x", cmd); - ps2_uart_write_byte(cmd); + ps2_uart_write_byte(dev, cmd); } -void ps2_uart_send_cmd_resend() { - struct ps2_uart_data *data = &ps2_uart_data; +void ps2_uart_send_cmd_resend(const struct device *dev) { + struct ps2_uart_data *data = dev->data; if (k_is_in_isr()) { @@ -469,7 +453,8 @@ void ps2_uart_send_cmd_resend() { // inhibition delay worker will never be called. k_work_submit_to_queue(&ps2_uart_work_queue_cb, &data->resend_cmd_work); } else { - ps2_uart_send_cmd_resend_worker(NULL); + // ps2_uart_send_cmd_resend_worker(NULL); + k_work_submit_to_queue(&ps2_uart_work_queue_cb, &data->resend_cmd_work); } } @@ -520,12 +505,13 @@ int ps2_uart_get_pinctrl_port_pin(const struct pinctrl_dev_config *pcfg, uint8_t * Reading PS2 data */ static void ps2_uart_interrupt_handler(const struct device *uart_dev, void *user_data); -void ps2_uart_read_interrupt_handler(); +void ps2_uart_read_interrupt_handler(const struct device *uart_dev, void *user_data); static int ps2_uart_read_err_check(const struct device *dev); -void ps2_uart_read_process_received_byte(uint8_t byte); +void ps2_uart_read_process_received_byte(const struct device *dev, uint8_t byte); const char *ps2_uart_read_get_error_str(int err); static void ps2_uart_interrupt_handler(const struct device *uart_dev, void *user_data) { + // const struct device* dev = (const struct device*)user_data; int err; err = uart_irq_update(uart_dev); @@ -540,6 +526,7 @@ static void ps2_uart_interrupt_handler(const struct device *uart_dev, void *user } void ps2_uart_read_interrupt_handler(const struct device *uart_dev, void *user_data) { + const struct device* dev = (const struct device*)user_data; uint8_t byte; int byte_len = uart_fifo_read(uart_dev, &byte, 1); @@ -548,7 +535,7 @@ void ps2_uart_read_interrupt_handler(const struct device *uart_dev, void *user_d return; } - ps2_uart_read_process_received_byte(byte); + ps2_uart_read_process_received_byte(dev, byte); } static int ps2_uart_read_err_check(const struct device *dev) { @@ -576,9 +563,9 @@ static int ps2_uart_read_err_check(const struct device *dev) { return err; } -void ps2_uart_read_process_received_byte(uint8_t byte) { - struct ps2_uart_data *data = &ps2_uart_data; - const struct ps2_uart_config *config = &ps2_uart_config; +void ps2_uart_read_process_received_byte(const struct device *dev, uint8_t byte) { + struct ps2_uart_data *data = dev->data; + const struct ps2_uart_config *config = dev->config; int err; @@ -626,7 +613,7 @@ void ps2_uart_read_process_received_byte(uint8_t byte) { data->callback_byte = byte; k_work_submit_to_queue(&ps2_uart_work_queue_cb, &data->callback_work); } else { - ps2_uart_data_queue_add(byte); + ps2_uart_data_queue_add(dev, byte); } } @@ -648,7 +635,12 @@ const char *ps2_uart_read_get_error_str(int err) { } void ps2_uart_read_callback_work_handler(struct k_work *work) { - struct ps2_uart_data *data = &ps2_uart_data; + + // struct k_work_delayable *work_delayable = (struct k_work_delayable *)item; + struct ps2_uart_data *data = CONTAINER_OF(work, + struct ps2_uart_data, + callback_work); + // const struct device *dev = data->dev; data->callback_isr(data->dev, data->callback_byte); data->callback_byte = 0x0; @@ -658,13 +650,13 @@ void ps2_uart_read_callback_work_handler(struct k_work *work) { * Writing PS2 data */ -int ps2_uart_write_byte_await_response(uint8_t byte); -int ps2_uart_write_byte_blocking(uint8_t byte); -int ps2_uart_write_byte_start(uint8_t byte); +int ps2_uart_write_byte_await_response(const struct device *dev, uint8_t byte); +int ps2_uart_write_byte_blocking(const struct device *dev, uint8_t byte); +int ps2_uart_write_byte_start(const struct device *dev, uint8_t byte); void ps2_uart_write_scl_interrupt_handler(const struct device *dev, struct gpio_callback *cb, uint32_t pins); void ps2_uart_write_scl_timeout(struct k_work *item); -void ps2_uart_write_finish(bool successful, char *descr); +void ps2_uart_write_finish(const struct device *dev, bool successful, char *descr); // Returned when there was an error writing to the PS2 device, such // as not getting a clock from the device or receiving an invalid @@ -691,19 +683,19 @@ void ps2_uart_write_finish(bool successful, char *descr); K_MUTEX_DEFINE(ps2_uart_write_mutex); -int ps2_uart_write_byte_debug(uint8_t byte) { +int ps2_uart_write_byte_debug(const struct device *dev, uint8_t byte) { int err; LOG_WRN("DEBUG WRITE STARTED for byte 0x%x", byte); LOG_WRN("Setting Write mode"); - err = ps2_uart_set_mode_write(); + err = ps2_uart_set_mode_write(dev); if (err != 0) { LOG_ERR("Could not configure driver for write mode: %d", err); return err; } // k_sleep(K_MSEC(1000)); - // err = ps2_uart_set_mode_write(); + // err = ps2_uart_set_mode_write(dev); // if (err != 0) { // LOG_ERR("Could not configure driver for write mode: %d", err); // return err; @@ -712,50 +704,50 @@ int ps2_uart_write_byte_debug(uint8_t byte) { // Inhibit the line by setting clock low and data high for 100us LOG_INF("Setting low"); - ps2_uart_set_scl(0); - ps2_uart_set_sda(0); + ps2_uart_set_scl(dev, 0); + ps2_uart_set_sda(dev, 0); k_sleep(K_MSEC(100)); LOG_INF("Setting high"); - ps2_uart_set_scl(1); - ps2_uart_set_sda(1); + ps2_uart_set_scl(dev, 1); + ps2_uart_set_sda(dev, 1); k_sleep(K_MSEC(100)); LOG_INF("Setting low"); - ps2_uart_set_scl(0); - ps2_uart_set_sda(0); + ps2_uart_set_scl(dev, 0); + ps2_uart_set_sda(dev, 0); k_sleep(K_MSEC(100)); LOG_INF("Setting high"); - ps2_uart_set_scl(1); - ps2_uart_set_sda(1); + ps2_uart_set_scl(dev, 1); + ps2_uart_set_sda(dev, 1); k_sleep(K_MSEC(100)); LOG_INF("Setting low"); - ps2_uart_set_scl(0); - ps2_uart_set_sda(0); + ps2_uart_set_scl(dev, 0); + ps2_uart_set_sda(dev, 0); k_sleep(K_MSEC(100)); LOG_INF("Setting high"); - ps2_uart_set_scl(1); - ps2_uart_set_sda(1); + ps2_uart_set_scl(dev, 1); + ps2_uart_set_sda(dev, 1); k_sleep(K_MSEC(100)); LOG_INF("Setting low"); - ps2_uart_set_scl(0); - ps2_uart_set_sda(0); + ps2_uart_set_scl(dev, 0); + ps2_uart_set_sda(dev, 0); k_sleep(K_MSEC(100)); LOG_WRN("Enabling interrupt callback"); - ps2_uart_set_scl_callback_enabled(true); + ps2_uart_set_scl_callback_enabled(dev, true); LOG_WRN("Setting SCL input"); - ps2_uart_configure_pin_scl_input(); + ps2_uart_configure_pin_scl_input(dev); k_sleep(K_MSEC(300)); LOG_WRN("Switching back to mode read"); - err = ps2_uart_set_mode_read(); + err = ps2_uart_set_mode_read(dev); if (err != 0) { LOG_ERR("Could not configure driver for write mode: %d", err); return err; @@ -766,7 +758,7 @@ int ps2_uart_write_byte_debug(uint8_t byte) { return -1; } -int ps2_uart_write_byte(uint8_t byte) { +int ps2_uart_write_byte(const struct device *dev, uint8_t byte) { int err; LOG_DBG("\n"); @@ -779,7 +771,7 @@ int ps2_uart_write_byte(uint8_t byte) { LOG_WRN("Attempting write re-try #%d of %d...", i + 1, PS2_UART_WRITE_MAX_RETRY); } - err = ps2_uart_write_byte_await_response(byte); + err = ps2_uart_write_byte_await_response(dev, byte); if (err == 0) { if (i > 0) { @@ -806,11 +798,11 @@ int ps2_uart_write_byte(uint8_t byte) { // Returns success if the response is 0xfa (ack) or any value except of // 0xfe. // 0xfe, 0xfc and 0xfa are not passed on to the read data queue or callback. -int ps2_uart_write_byte_await_response(uint8_t byte) { - struct ps2_uart_data *data = &ps2_uart_data; +int ps2_uart_write_byte_await_response(const struct device *dev, uint8_t byte) { + struct ps2_uart_data *data = dev->data; int err; - err = ps2_uart_write_byte_blocking(byte); + err = ps2_uart_write_byte_blocking(dev, byte); if (err) { return err; } @@ -852,13 +844,13 @@ int ps2_uart_write_byte_await_response(uint8_t byte) { return 0; } -int ps2_uart_write_byte_blocking(uint8_t byte) { - struct ps2_uart_data *data = &ps2_uart_data; +int ps2_uart_write_byte_blocking(const struct device *dev, uint8_t byte) { + struct ps2_uart_data *data = dev->data; int err; // LOG_DBG("ps2_uart_write_byte_blocking called with byte=0x%x", byte); - err = ps2_uart_write_byte_start(byte); + err = ps2_uart_write_byte_start(dev, byte); if (err) { LOG_ERR("Could not initiate writing of byte."); return PS2_UART_E_WRITE_TRANSMIT; @@ -896,8 +888,8 @@ int ps2_uart_write_byte_blocking(uint8_t byte) { return err; } -int ps2_uart_write_byte_start(uint8_t byte) { - struct ps2_uart_data *data = &ps2_uart_data; +int ps2_uart_write_byte_start(const struct device *dev, uint8_t byte) { + struct ps2_uart_data *data = dev->data; int err; // Take semaphore so that when `ps2_uart_write_byte_blocking` attempts @@ -909,7 +901,7 @@ int ps2_uart_write_byte_start(uint8_t byte) { return err; } - err = ps2_uart_set_mode_write(); + err = ps2_uart_set_mode_write(dev); if (err != 0) { LOG_ERR("Could not configure driver for write mode: %d", err); return err; @@ -922,12 +914,12 @@ int ps2_uart_write_byte_start(uint8_t byte) { data->cur_write_pos = PS2_UART_POS_START; // Inhibit the line by setting clock low and data high for 100us - ps2_uart_set_scl(0); - ps2_uart_set_sda(1); + ps2_uart_set_scl(dev, 0); + ps2_uart_set_sda(dev, 1); k_busy_wait(PS2_UART_TIMING_SCL_INHIBITION); // Set data to value of start bit - ps2_uart_set_sda(0); + ps2_uart_set_sda(dev, 0); k_busy_wait(PS2_UART_TIMING_SCL_INHIBITION); // The start bit was sent by setting sda to low @@ -937,13 +929,13 @@ int ps2_uart_write_byte_start(uint8_t byte) { // Release the clock line and configure it as input // This let's the device take control of the clock again - ps2_uart_set_scl(1); - ps2_uart_configure_pin_scl_input(); + ps2_uart_set_scl(dev, 1); + ps2_uart_configure_pin_scl_input(dev); // We need to wait for the first SCL clock // Execution continues once it arrives in // `ps2_uart_write_scl_interrupt_handler` - ps2_uart_set_scl_callback_enabled(true); + ps2_uart_set_scl_callback_enabled(dev, true); // And if the PS/2 device doesn't start the clock, we want to // handle that error... @@ -956,13 +948,20 @@ int ps2_uart_write_byte_start(uint8_t byte) { } void ps2_uart_write_scl_timeout(struct k_work *item) { + + struct k_work_delayable *work_delayable = (struct k_work_delayable *)item; + struct ps2_uart_data *data = CONTAINER_OF(work_delayable, + struct ps2_uart_data, + write_scl_timout); + const struct device *dev = data->dev; + // Once we start a transmission we expect the device to // to send a new clock/interrupt within // PS2_UART_TIMEOUT_WRITE_SCL_START us. // If we don't receive the next interrupt within that timeframe, // we abort the write. - ps2_uart_write_finish(false, "scl timeout"); + ps2_uart_write_finish(dev, false, "scl timeout"); } // The nrf52 is too slow to process all SCL interrupts, so we @@ -980,10 +979,10 @@ void ps2_uart_write_scl_timeout(struct k_work *item) { // So, we use a GPIO interrupt to wait for the first clock cycle and // then use delays to send the actual data at the same rate as the // UART baud rate. -void ps2_uart_write_scl_interrupt_handler_blocking(const struct device *dev, - struct gpio_callback *cb, uint32_t pins) { - struct ps2_uart_data *data = &ps2_uart_data; - +void ps2_uart_write_scl_interrupt_handler_blocking(struct ps2_uart_data *data, + const struct device *gpio_dev, + struct gpio_callback *cb, + uint32_t pins) { LOG_INF("Inside ps2_uart_write_scl_interrupt_handler_blocking"); // Cancel the SCL timeout @@ -991,7 +990,7 @@ void ps2_uart_write_scl_interrupt_handler_blocking(const struct device *dev, // Disable the SCL interrupt again. // From here we will just use time delays. - ps2_uart_set_scl_callback_enabled(false); + ps2_uart_set_scl_callback_enabled(data->dev, false); for (int i = PS2_UART_POS_DATA_FIRST; i <= PS2_UART_POS_STOP; i++) { @@ -1000,20 +999,20 @@ void ps2_uart_write_scl_interrupt_handler_blocking(const struct device *dev, int data_pos = i - PS2_UART_POS_DATA_FIRST; bool data_bit = PS2_UART_GET_BIT(data->cur_write_byte, data_pos); - ps2_uart_set_sda(data_bit); + ps2_uart_set_sda(data->dev, data_bit); } else if (i == PS2_UART_POS_PARITY) { bool byte_parity = ps2_uart_get_byte_parity(data->cur_write_byte); - ps2_uart_set_sda(byte_parity); + ps2_uart_set_sda(data->dev, byte_parity); } else if (i == PS2_UART_POS_STOP) { - ps2_uart_set_sda(1); + ps2_uart_set_sda(data->dev, 1); // Give control over data pin back to device after sending // the stop bit so that we can receive the ack bit from the // device - ps2_uart_configure_pin_sda_input(); + ps2_uart_configure_pin_sda_input(data->dev); } else { LOG_ERR("UART unknown TX bit number: %d", i); } @@ -1023,21 +1022,21 @@ void ps2_uart_write_scl_interrupt_handler_blocking(const struct device *dev, } // Check Ack - int ack_val = ps2_uart_get_sda(); + int ack_val = ps2_uart_get_sda(data->dev); if (ack_val == 0) { - ps2_uart_write_finish(true, "successful ack"); + ps2_uart_write_finish(data->dev, true, "successful ack"); } else { // TODO: Properly handle write ack errors LOG_WRN("Ack bit was invalid for write of 0x%x", data->cur_write_byte); - ps2_uart_write_finish(true, "failed ack"); + ps2_uart_write_finish(data->dev, true, "failed ack"); } } -void ps2_uart_write_scl_interrupt_handler_async(const struct device *dev, struct gpio_callback *cb, +void ps2_uart_write_scl_interrupt_handler_async(struct ps2_uart_data *data, + const struct device *gpio_dev, + struct gpio_callback *cb, uint32_t pins) { - struct ps2_uart_data *data = &ps2_uart_data; - k_work_cancel_delayable(&data->write_scl_timout); if (data->cur_write_pos == PS2_UART_POS_START) { @@ -1050,30 +1049,30 @@ void ps2_uart_write_scl_interrupt_handler_async(const struct device *dev, struct int data_pos = data->cur_write_pos - PS2_UART_POS_DATA_FIRST; bool data_bit = PS2_UART_GET_BIT(data->cur_write_byte, data_pos); - ps2_uart_set_sda(data_bit); + ps2_uart_set_sda(data->dev, data_bit); } else if (data->cur_write_pos == PS2_UART_POS_PARITY) { bool byte_parity = ps2_uart_get_byte_parity(data->cur_write_byte); - ps2_uart_set_sda(byte_parity); + ps2_uart_set_sda(data->dev, byte_parity); } else if (data->cur_write_pos == PS2_UART_POS_STOP) { - ps2_uart_set_sda(1); + ps2_uart_set_sda(data->dev, 1); // Give control over data pin back to device after sending // the stop bit so that we can receive the ack bit from the // device - ps2_uart_configure_pin_sda_input(); + ps2_uart_configure_pin_sda_input(data->dev); } else if (data->cur_write_pos == PS2_UART_POS_ACK) { - int ack_val = ps2_uart_get_sda(); + int ack_val = ps2_uart_get_sda(data->dev); if (ack_val == 0) { - ps2_uart_write_finish(true, "successful ack"); + ps2_uart_write_finish(data->dev, true, "successful ack"); } else { // TODO: Properly handle write ack errors LOG_WRN("Ack bit was invalid for write of 0x%x", data->cur_write_byte); - ps2_uart_write_finish(true, "failed ack"); + ps2_uart_write_finish(data->dev, true, "failed ack"); } } else { LOG_ERR("UART unknown TX bit number: %d", data->cur_write_pos); @@ -1087,8 +1086,8 @@ void ps2_uart_write_scl_interrupt_handler_async(const struct device *dev, struct data->cur_write_pos += 1; } -void ps2_uart_write_finish(bool successful, char *descr) { - struct ps2_uart_data *data = &ps2_uart_data; +void ps2_uart_write_finish(const struct device *dev, bool successful, char *descr) { + struct ps2_uart_data *data = dev->data; int err; k_work_cancel_delayable(&data->write_scl_timout); @@ -1102,7 +1101,7 @@ void ps2_uart_write_finish(bool successful, char *descr) { data->cur_write_status = PS2_UART_WRITE_STATUS_FAILURE; } - err = ps2_uart_set_mode_read(); + err = ps2_uart_set_mode_read(dev); if (err != 0) { LOG_ERR("Could not configure driver for read mode: %d", err); return; @@ -1164,7 +1163,7 @@ static int ps2_uart_configure(const struct device *dev, ps2_callback_t callback_ int ps2_uart_read(const struct device *dev, uint8_t *value) { uint8_t queue_byte; - int err = ps2_uart_data_queue_get_next(&queue_byte, PS2_UART_TIMEOUT_READ); + int err = ps2_uart_data_queue_get_next(dev, &queue_byte, PS2_UART_TIMEOUT_READ); if (err) { // Timeout due to no data to read in data queue // LOG_DBG("ps2_uart_read: Fifo timed out..."); @@ -1178,7 +1177,7 @@ int ps2_uart_read(const struct device *dev, uint8_t *value) { } static int ps2_uart_write(const struct device *dev, uint8_t value) { - int ret = ps2_uart_write_byte(value); + int ret = ps2_uart_write_byte(dev, value); return ret; } @@ -1188,7 +1187,7 @@ static int ps2_uart_disable_callback(const struct device *dev) { // Make sure there are no stale items in the data queue // from before the callback was disabled. - ps2_uart_data_queue_empty(); + ps2_uart_data_queue_empty(dev); data->callback_enabled = false; @@ -1203,7 +1202,7 @@ static int ps2_uart_enable_callback(const struct device *dev) { // LOG_DBG("Enabled PS2 callback."); - ps2_uart_data_queue_empty(); + ps2_uart_data_queue_empty(dev); return 0; } @@ -1219,18 +1218,31 @@ static const struct ps2_driver_api ps2_uart_driver_api = { /* * PS/2 UART Driver Init */ -static int ps2_uart_init_uart(void); -static int ps2_uart_init_gpio(void); +static int ps2_uart_init_uart(const struct device *dev); +static int ps2_uart_init_gpio(const struct device *dev); static int ps2_uart_init(const struct device *dev) { int err; struct ps2_uart_data *data = dev->data; - struct ps2_uart_config *config = (struct ps2_uart_config *)&ps2_uart_config; + const struct ps2_uart_config *config = dev->config; // Set the ps2 device so we can retrieve it later for // the ps2 callback data->dev = dev; + data->callback_byte = 0x0; + data->callback_isr = NULL; + data->callback_enabled = false; + data->cur_write_status = PS2_UART_WRITE_STATUS_INACTIVE; + data->cur_write_byte = 0x0; + data->cur_write_pos = 0; + data->write_awaits_resp = false; + data->write_awaits_resp_byte = 0x0; + +#if IS_ENABLED(CONFIG_PS2_UART_ENABLE_PS2_RESEND_CALLBACK) + data->resend_callback_isr = NULL; +#endif /* IS_ENABLED(CONFIG_PS2_UART_ENABLE_PS2_RESEND_CALLBACK) */ + // Get the P0.08 pin notation of the configured UART pinctrl pin. // The UART TX pin is the second (index 1) of the pins int pinctrl_port = -1; @@ -1267,19 +1279,19 @@ static int ps2_uart_init(const struct device *dev) { // Init semaphore that waits for read after write k_sem_init(&data->write_awaits_resp_sem, 0, 1); - err = ps2_uart_init_uart(); + err = ps2_uart_init_uart(dev); if (err != 0) { LOG_ERR("Could not init UART: %d", err); return err; } - err = ps2_uart_init_gpio(); + err = ps2_uart_init_gpio(dev); if (err != 0) { LOG_ERR("Could not init GPIO: %d", err); return err; } - err = ps2_uart_set_mode_read(); + err = ps2_uart_set_mode_read(dev); if (err != 0) { LOG_ERR("Could not initialize in UART mode read: %d", err); return err; @@ -1288,9 +1300,9 @@ static int ps2_uart_init(const struct device *dev) { return 0; } -static int ps2_uart_init_uart(void) { - struct ps2_uart_data *data = &ps2_uart_data; - struct ps2_uart_config *config = (struct ps2_uart_config *)&ps2_uart_config; +static int ps2_uart_init_uart(const struct device *dev) { + struct ps2_uart_data *data = dev->data; + const struct ps2_uart_config *config = dev->config; int err; if (!device_is_ready(config->uart_dev)) { @@ -1330,17 +1342,17 @@ static int ps2_uart_init_uart(void) { return 0; } -static int ps2_uart_init_gpio(void) { - struct ps2_uart_data *data = &ps2_uart_data; - struct ps2_uart_config *config = (struct ps2_uart_config *)&ps2_uart_config; +static int ps2_uart_init_gpio(const struct device *dev) { + struct ps2_uart_data *data = dev->data; + const struct ps2_uart_config *config = dev->config; int err; // Interrupt for clock line #if IS_ENABLED(CONFIG_PS2_UART_WRITE_MODE_BLOCKING) - gpio_init_callback(&data->scl_cb_data, ps2_uart_write_scl_interrupt_handler_blocking, + gpio_init_callback(&data->scl_cb_data, data->scl_rupt_blocking, BIT(config->scl_gpio.pin)); -#else - gpio_init_callback(&data->scl_cb_data, ps2_uart_write_scl_interrupt_handler_async, +#else /* IS_ENABLED(CONFIG_PS2_UART_WRITE_MODE_BLOCKING) */ + gpio_init_callback(&data->scl_cb_data, data->scl_rupt_async, BIT(config->scl_gpio.pin)); #endif /* IS_ENABLED(CONFIG_PS2_UART_WRITE_MODE_BLOCKING) */ @@ -1352,10 +1364,53 @@ static int ps2_uart_init_gpio(void) { } LOG_INF("Disabling callback..."); - ps2_uart_set_scl_callback_enabled(false); + ps2_uart_set_scl_callback_enabled(dev, false); return err; } -DEVICE_DT_INST_DEFINE(0, &ps2_uart_init, NULL, &ps2_uart_data, &ps2_uart_config, POST_KERNEL, 80, - &ps2_uart_driver_api); + +// Define wrapper function declaration for write_scl_interrupt_handler_* +// will assign to ps2_uart_data in below +#define PS2_UART_SCL_INTERRUPT_DEFINE(n) \ + void ps2_uart_write_scl_interrupt_handler_blocking_##n( \ + const struct device *gpio_dev, struct gpio_callback *cb, uint32_t pins); \ + void ps2_uart_write_scl_interrupt_handler_async_##n( \ + const struct device *gpio_dev, struct gpio_callback *cb, uint32_t pins); + +DT_INST_FOREACH_STATUS_OKAY(PS2_UART_SCL_INTERRUPT_DEFINE) + + +#define PS2_UART_DEFINE(n) \ + static struct ps2_uart_data data##n = { \ + .scl_rupt_blocking = &ps2_uart_write_scl_interrupt_handler_blocking_##n, \ + .scl_rupt_async = &ps2_uart_write_scl_interrupt_handler_async_##n, \ + }; \ + static const struct ps2_uart_config config##n = { \ + .uart_dev = DEVICE_DT_GET(DT_INST_BUS(n)), \ + .scl_gpio = GPIO_DT_SPEC_INST_GET(n, scl_gpios), \ + .sda_gpio = GPIO_DT_SPEC_INST_GET(n, sda_gpios), \ + .pcfg = PINCTRL_DT_DEV_CONFIG_GET(DT_INST_BUS(n)), \ + .scl_gpio_port_num = DT_PROP(DT_INST_PHANDLE(n, scl_gpios), port), \ + .sda_gpio_port_num = DT_PROP(DT_INST_PHANDLE(n, sda_gpios), port), \ + }; \ + DEVICE_DT_INST_DEFINE(0, &ps2_uart_init, NULL, &data##n, &config##n, \ + POST_KERNEL, 80, \ + &ps2_uart_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(PS2_UART_DEFINE) + + +// Define wrapper function implementation for write_scl_interrupt_handler_* +// assigned to ps2_uart_data on above +#define PS2_UART_SCL_INTERRUPT_IMPL_DEFINE(n) \ + void ps2_uart_write_scl_interrupt_handler_blocking_##n( \ + const struct device *gpio_dev, struct gpio_callback *cb, uint32_t pins) { \ + ps2_uart_write_scl_interrupt_handler_blocking(&data##n, gpio_dev, cb, pins); \ + } \ + void ps2_uart_write_scl_interrupt_handler_async_##n( \ + const struct device *gpio_dev, struct gpio_callback *cb, uint32_t pins) { \ + ps2_uart_write_scl_interrupt_handler_async(&data##n, gpio_dev, cb, pins); \ + } + +DT_INST_FOREACH_STATUS_OKAY(PS2_UART_SCL_INTERRUPT_IMPL_DEFINE) From 0be671ec7920d54ca6a1d41ad2cd7f9df24b71b3 Mon Sep 17 00:00:00 2001 From: Jeff Leung Date: Tue, 30 Jul 2024 23:35:45 +0800 Subject: [PATCH 4/5] fix ps2_uart_work_queue for dual TPs --- src/drivers/input/input_mouse_ps2.c | 2 +- src/drivers/ps2/ps2_uart.c | 26 ++++++++++++++++---------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/drivers/input/input_mouse_ps2.c b/src/drivers/input/input_mouse_ps2.c index e3b4848..52b9e67 100644 --- a/src/drivers/input/input_mouse_ps2.c +++ b/src/drivers/input/input_mouse_ps2.c @@ -1996,7 +1996,7 @@ DT_INST_FOREACH_STATUS_OKAY(PS2_MOUSE_CALLBACK_DEFINE) .tp_y_invert = DT_INST_PROP_OR(n, tp_y_invert, false), \ .tp_xy_swap = DT_INST_PROP_OR(n, tp_xy_swap, false), \ }; \ - DEVICE_DT_INST_DEFINE(0, &zmk_mouse_ps2_init, NULL, &data##n, &config##n, \ + DEVICE_DT_INST_DEFINE(n, &zmk_mouse_ps2_init, NULL, &data##n, &config##n, \ POST_KERNEL, ZMK_MOUSE_PS2_INIT_PRIORITY, NULL); DT_INST_FOREACH_STATUS_OKAY(ZMK_PS2_MOUSE_DEFINE) diff --git a/src/drivers/ps2/ps2_uart.c b/src/drivers/ps2/ps2_uart.c index 2aeecf7..33a2572 100644 --- a/src/drivers/ps2/ps2_uart.c +++ b/src/drivers/ps2/ps2_uart.c @@ -24,7 +24,7 @@ LOG_MODULE_REGISTER(ps2_uart); * Pin Control */ -PINCTRL_DT_DEFINE(DT_INST_BUS(0)); +// PINCTRL_DT_DEFINE(DT_INST_BUS(0)); // moved to PS2_UART_DEFINE(n) /* * Settings @@ -146,6 +146,8 @@ struct ps2_uart_data_queue_item { }; struct ps2_uart_config { + int ps2_uart_idx; + const struct device *uart_dev; struct gpio_dt_spec scl_gpio; struct gpio_dt_spec sda_gpio; @@ -1259,15 +1261,17 @@ static int ps2_uart_init(const struct device *dev) { k_msgq_init(&data->data_queue, data->data_queue_buffer, sizeof(struct ps2_uart_data_queue_item), PS2_UART_DATA_QUEUE_SIZE); - // Custom queue for background PS/2 processing work at high priority - k_work_queue_start(&ps2_uart_work_queue, ps2_uart_work_queue_stack_area, - K_THREAD_STACK_SIZEOF(ps2_uart_work_queue_stack_area), - PS2_UART_WORK_QUEUE_PRIORITY, NULL); + if (config->ps2_uart_idx == 0) { + // Custom queue for background PS/2 processing work at high priority + k_work_queue_start(&ps2_uart_work_queue, ps2_uart_work_queue_stack_area, + K_THREAD_STACK_SIZEOF(ps2_uart_work_queue_stack_area), + PS2_UART_WORK_QUEUE_PRIORITY, NULL); - // Custom queue for calling the zephyr ps/2 callback at lower priority - k_work_queue_start(&ps2_uart_work_queue_cb, ps2_uart_work_queue_cb_stack_area, - K_THREAD_STACK_SIZEOF(ps2_uart_work_queue_cb_stack_area), - PS2_UART_WORK_QUEUE_CB_PRIORITY, NULL); + // Custom queue for calling the zephyr ps/2 callback at lower priority + k_work_queue_start(&ps2_uart_work_queue_cb, ps2_uart_work_queue_cb_stack_area, + K_THREAD_STACK_SIZEOF(ps2_uart_work_queue_cb_stack_area), + PS2_UART_WORK_QUEUE_CB_PRIORITY, NULL); + } k_work_init(&data->callback_work, ps2_uart_read_callback_work_handler); @@ -1382,11 +1386,13 @@ DT_INST_FOREACH_STATUS_OKAY(PS2_UART_SCL_INTERRUPT_DEFINE) #define PS2_UART_DEFINE(n) \ + PINCTRL_DT_DEFINE(DT_INST_BUS(n)); \ static struct ps2_uart_data data##n = { \ .scl_rupt_blocking = &ps2_uart_write_scl_interrupt_handler_blocking_##n, \ .scl_rupt_async = &ps2_uart_write_scl_interrupt_handler_async_##n, \ }; \ static const struct ps2_uart_config config##n = { \ + .ps2_uart_idx = n, \ .uart_dev = DEVICE_DT_GET(DT_INST_BUS(n)), \ .scl_gpio = GPIO_DT_SPEC_INST_GET(n, scl_gpios), \ .sda_gpio = GPIO_DT_SPEC_INST_GET(n, sda_gpios), \ @@ -1394,7 +1400,7 @@ DT_INST_FOREACH_STATUS_OKAY(PS2_UART_SCL_INTERRUPT_DEFINE) .scl_gpio_port_num = DT_PROP(DT_INST_PHANDLE(n, scl_gpios), port), \ .sda_gpio_port_num = DT_PROP(DT_INST_PHANDLE(n, sda_gpios), port), \ }; \ - DEVICE_DT_INST_DEFINE(0, &ps2_uart_init, NULL, &data##n, &config##n, \ + DEVICE_DT_INST_DEFINE(n, &ps2_uart_init, NULL, &data##n, &config##n, \ POST_KERNEL, 80, \ &ps2_uart_driver_api); From d0c563008b585e3582908d94ab17221c18b9f906 Mon Sep 17 00:00:00 2001 From: Jeff Leung Date: Wed, 14 Aug 2024 00:59:05 +0800 Subject: [PATCH 5/5] fix compile error without zmk/mouse/hid.h --- src/mouse/input_listener_ps2.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/mouse/input_listener_ps2.c b/src/mouse/input_listener_ps2.c index 820f5fd..372ce24 100644 --- a/src/mouse/input_listener_ps2.c +++ b/src/mouse/input_listener_ps2.c @@ -18,7 +18,11 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); #include #include #include -#include +#include + +#ifndef ZMK_MOUSE_HID_NUM_BUTTONS +#define ZMK_MOUSE_HID_NUM_BUTTONS 0x05 +#endif #define ONE_IF_DEV_OK(n) \ COND_CODE_1(DT_NODE_HAS_STATUS(DT_INST_PHANDLE(n, device), okay), (1 +), (0 +))