Skip to content

Commit 3d0d1bf

Browse files
committed
drivers: ps2: Add resend callback to ps/2 interface
When the PS/2 driver detects an error in an incoming transmission, it’s supposed to send 0xfe to the device to ask it to resend the last packet. But a PS/2 packet can be more than one byte (such as a 3 or 4-byte mouse packet). So, on reception of the 0xfe resend command, the PS/2 device resends ALL bytes in the packet and not just the one where the transmission failed. This can cause the higher level driver’s packet buffer to become misaligned. This PR adds a callback that notifies the higher level driver when the PS/2 driver requested a resend so that the higher level driver can expect a new packet and doesn’t get misaligned.
1 parent 6f349d0 commit 3d0d1bf

File tree

4 files changed

+30
-8
lines changed

4 files changed

+30
-8
lines changed

drivers/ps2/ps2_handlers.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,16 @@
88
#include <zephyr/syscall_handler.h>
99

1010
static inline int z_vrfy_ps2_config(const struct device *dev,
11-
ps2_callback_t callback_isr)
11+
ps2_callback_t callback_isr,
12+
ps2_resend_callback_t resend_callback_isr)
13+
1214
{
1315
Z_OOPS(Z_SYSCALL_DRIVER_PS2(dev, config));
1416
Z_OOPS(Z_SYSCALL_VERIFY_MSG(callback_isr == NULL,
1517
"callback not be set from user mode"));
16-
return z_impl_ps2_config(dev, callback_isr);
18+
Z_OOPS(Z_SYSCALL_VERIFY_MSG(resend_callback_isr == NULL,
19+
"resend callback not be set from user mode"));
20+
return z_impl_ps2_config(dev, callback_isr, resend_callback_isr);
1721
}
1822
#include <syscalls/ps2_config_mrsh.c>
1923

drivers/ps2/ps2_mchp_xec.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,8 @@ static inline void ps2_xec_girq_en(const struct device *dev)
9494
#endif /* CONFIG_SOC_SERIES_MEC172X */
9595

9696
static int ps2_xec_configure(const struct device *dev,
97-
ps2_callback_t callback_isr)
97+
ps2_callback_t callback_isr,
98+
ps2_resend_callback_t resend_callback_isr)
9899
{
99100
const struct ps2_xec_config * const config = dev->config;
100101
struct ps2_xec_data * const data = dev->data;

drivers/ps2/ps2_npcx_channel.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ struct ps2_npcx_ch_config {
3737

3838
/* PS/2 api functions */
3939
static int ps2_npcx_ch_configure(const struct device *dev,
40-
ps2_callback_t callback_isr)
40+
ps2_callback_t callback_isr,
41+
ps2_resend_callback_t resend_callback_isr)
4142
{
4243
const struct ps2_npcx_ch_config *const config = dev->config;
4344
int ret;

include/zephyr/drivers/ps2.h

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,18 @@ extern "C" {
3737
*/
3838
typedef void (*ps2_callback_t)(const struct device *dev, uint8_t data);
3939

40+
/**
41+
* @brief PS/2 callback that is called when the PS/2 driver detects a
42+
* transmission error and instructs the PS/2 device to re-send the last PS/2
43+
* packet. A PS/2 packet can be more than one byte and when the device is
44+
* instructed to resend the last packet, it will resend all the bytes. This
45+
* can cause the PS/2 driver to become misaligned. This callback lets the PS/2
46+
* driver know that it should expect a resend of an entire packet.
47+
*
48+
* @param dev Pointer to the device structure for the driver instance.
49+
*/
50+
typedef void (*ps2_resend_callback_t)(const struct device *dev);
51+
4052
/**
4153
* @cond INTERNAL_HIDDEN
4254
*
@@ -45,7 +57,8 @@ typedef void (*ps2_callback_t)(const struct device *dev, uint8_t data);
4557
* (Internal use only.)
4658
*/
4759
typedef int (*ps2_config_t)(const struct device *dev,
48-
ps2_callback_t callback_isr);
60+
ps2_callback_t callback_isr,
61+
ps2_resend_callback_t resend_callback_isr);
4962
typedef int (*ps2_read_t)(const struct device *dev, uint8_t *value);
5063
typedef int (*ps2_write_t)(const struct device *dev, uint8_t value);
5164
typedef int (*ps2_disable_callback_t)(const struct device *dev);
@@ -73,15 +86,18 @@ __subsystem struct ps2_driver_api {
7386
* @retval Negative errno code if failure.
7487
*/
7588
__syscall int ps2_config(const struct device *dev,
76-
ps2_callback_t callback_isr);
89+
ps2_callback_t callback_isr,
90+
ps2_resend_callback_t resend_callback_isr);
7791

7892
static inline int z_impl_ps2_config(const struct device *dev,
79-
ps2_callback_t callback_isr)
93+
ps2_callback_t callback_isr,
94+
ps2_resend_callback_t resend_callback_isr)
95+
8096
{
8197
const struct ps2_driver_api *api =
8298
(struct ps2_driver_api *)dev->api;
8399

84-
return api->config(dev, callback_isr);
100+
return api->config(dev, callback_isr, resend_callback_isr);
85101
}
86102

87103
/**

0 commit comments

Comments
 (0)