1 /*
2  * Copyright (c) 2006-2023, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2021-11-11     GuEe-GUI     the first version
9  */
10 
11 #ifndef __VIRTIO_INPUT_H__
12 #define __VIRTIO_INPUT_H__
13 
14 #include <rtdef.h>
15 
16 #include <virtio.h>
17 #include <virtio_input_event_codes.h>
18 
19 #define VIRTIO_INPUT_QUEUE_EVENT        0
20 #define VIRTIO_INPUT_QUEUE_STATUS       1
21 #define VIRTIO_INPUT_EVENT_QUEUE_SIZE   64
22 #define VIRTIO_INPUT_STATUS_QUEUE_SIZE  8
23 #define VIRTIO_INPUT_QUEUE_MAX_SIZE     (VIRTIO_INPUT_EVENT_QUEUE_SIZE > VIRTIO_INPUT_STATUS_QUEUE_SIZE ? \
24         VIRTIO_INPUT_EVENT_QUEUE_SIZE : VIRTIO_INPUT_STATUS_QUEUE_SIZE)
25 
26 #define VIRTIO_INPUT_ABS_AXIS_X         0
27 #define VIRTIO_INPUT_ABS_AXIS_Y         1
28 
29 enum virtio_input_type
30 {
31     VIRTIO_INPUT_TYPE_KEYBOARD,
32     VIRTIO_INPUT_TYPE_MOUSE,
33     VIRTIO_INPUT_TYPE_TABLET,
34 
35     VIRTIO_INPUT_TYPE_SIZE,
36 };
37 
38 enum virtio_input_config_select
39 {
40     VIRTIO_INPUT_CFG_UNSET      = 0x00,
41     VIRTIO_INPUT_CFG_ID_NAME    = 0x01,
42     VIRTIO_INPUT_CFG_ID_SERIAL  = 0x02,
43     VIRTIO_INPUT_CFG_ID_DEVIDS  = 0x03,
44     VIRTIO_INPUT_CFG_PROP_BITS  = 0x10,
45     VIRTIO_INPUT_CFG_EV_BITS    = 0x11,
46     VIRTIO_INPUT_CFG_ABS_INFO   = 0x12,
47 };
48 
49 struct virtio_input_absinfo
50 {
51     rt_uint32_t min;    /* Minimum value for the axis */
52     rt_uint32_t max;    /* Maximum value for the axis */
53     rt_uint32_t fuzz;   /* Fuzz value that is used to filter noise from the event stream */
54     rt_uint32_t flat;   /* Within this value will be discarded by joydev interface and reported as 0 instead */
55     rt_uint32_t res;    /* Resolution for the values reported for the axis */
56 };
57 
58 struct virtio_input_devids
59 {
60     rt_uint16_t bustype;
61     rt_uint16_t vendor;
62     rt_uint16_t product;
63     rt_uint16_t version;
64 };
65 
66 struct virtio_input_config
67 {
68     rt_uint8_t select;
69     rt_uint8_t subsel;
70     rt_uint8_t size;
71     rt_uint8_t reserved[5];
72 
73     union
74     {
75         char string[128];
76         rt_uint8_t bitmap[128];
77         struct virtio_input_absinfo abs;
78         struct virtio_input_devids ids;
79     };
80 } __attribute__((packed));
81 
82 struct virtio_input_event
83 {
84     rt_uint16_t type;
85     rt_uint16_t code;
86     rt_uint32_t value;
87 };
88 
89 #ifdef ARCH_CPU_64BIT
90 #define BITS_PER_LONG 64
91 #else
92 #define BITS_PER_LONG 32
93 #endif
94 #define BIT_MASK(nr)        (1UL << ((nr) % BITS_PER_LONG))
95 #define BIT_WORD(nr)        ((nr) / BITS_PER_LONG)
96 #define DIV_ROUND_UP(n, d)  (((n) + (d) - 1) / (d))
97 
98 #define BITS_PER_BYTE       8
99 #define BITS_PER_TYPE(type) (sizeof(type) * BITS_PER_BYTE)
100 #define BITS_TO_BYTES(nr)   DIV_ROUND_UP(nr, BITS_PER_TYPE(char))
101 #define BITS_TO_LONGS(nr)   DIV_ROUND_UP(nr, BITS_PER_TYPE(long))
102 
103 struct virtio_input_device
104 {
105     struct rt_device parent;
106 
107     struct virtio_device virtio_dev;
108 
109     rt_ubase_t ev_bit[BITS_TO_LONGS(EV_CNT)];
110     rt_ubase_t key_bit[BITS_TO_LONGS(KEY_CNT)];
111     rt_ubase_t rel_bit[BITS_TO_LONGS(REL_CNT)];
112     rt_ubase_t abs_bit[BITS_TO_LONGS(ABS_CNT)];
113 
114     enum virtio_input_type type;
115     struct virtio_input_config *config;
116 
117     /* Broadcast events */
118     struct rt_mutex rw_mutex;
119     void (*bsct_handler)(struct virtio_input_event event);
120     struct virtio_input_event bcst_events[VIRTIO_INPUT_EVENT_QUEUE_SIZE];
121 
122     /* Receive events */
123     struct virtio_input_event recv_events[VIRTIO_INPUT_EVENT_QUEUE_SIZE];
124 
125     /* Transmit status */
126     struct virtio_input_event xmit_events[VIRTIO_INPUT_STATUS_QUEUE_SIZE];
127 };
128 
129 enum
130 {
131     VIRTIO_DEVICE_CTRL_INPUT_GET_TYPE           = 0x20,
132     VIRTIO_DEVICE_CTRL_INPUT_BIND_BSCT_HANDLER,
133     VIRTIO_DEVICE_CTRL_INPUT_GET_ABS_X_INFO,
134     VIRTIO_DEVICE_CTRL_INPUT_GET_ABS_Y_INFO,
135     VIRTIO_DEVICE_CTRL_INPUT_SET_STATUS,
136 
137     VIRTIO_DEVICE_CTRL_INPUT_GET_EV_BIT,
138     VIRTIO_DEVICE_CTRL_INPUT_GET_KEY_BIT,
139     VIRTIO_DEVICE_CTRL_INPUT_GET_REL_BIT,
140     VIRTIO_DEVICE_CTRL_INPUT_GET_ABS_BIT,
141 };
142 
143 rt_err_t rt_virtio_input_init(rt_ubase_t *mmio_base, rt_uint32_t irq);
144 
145 #endif /* __VIRTIO_INPUT_H__ */
146